#asp.net-mvc-3 #ninject
#asp.net-mvc-3 #ninject
Вопрос:
Я создаю приложение с использованием Ninject и ASP.NET MVC 3. Возможно ли с помощью Ninject предоставить общую привязку в модуле, подобном этому:
Bind(typeof(IRepository<>)).To(typeof(SomeConcreteRepository<>));
Редактировать:
А затем для определенного типа создайте класс, который наследуется от SomeConcreteRepository:
Bind(typeof(IRepository<Person>)).To(typeof(PersonConcreteRepository));
Это вызывает исключение, что доступно несколько привязок. Однако, есть ли другой подход к этому? Существуют ли другие платформы DI для .NET, которые поддерживают такое поведение?
Ответ №1:
Вам не нужна вторая строка. Просто зарегистрируйте открытые универсальные типы:
kernel.Bind(typeof(IRepository<>)).To(typeof(SomeConcreteRepository<>));
и позже извлеките конкретный репозиторий, подобный этому:
var repo = kernel.Get<IRepository<Person>>();
или вы также можете использовать поставщика.
Комментарии:
1. @sTodorov, вы видели ссылку на поставщика, которую я опубликовал в своем ответе?
2. Да, я действительно поблагодарил вас. В настоящее время я изучаю возможность расширения поставщиков или создания настроенного ядра и переопределения нескольких методов. Расскажет вам, как это происходит.
3. спасибо за вашу помощь. Исправлено другим способом. Смотрите ответ выше
Ответ №2:
Немного неприятное исправление, но для рассматриваемого сценария оно работает:
public class MyKernel: StandardKernel
{
public MyKernel(params INinjectModule[] modules) : base(modules) { }
public MyKernel(INinjectSettings settings, params INinjectModule[] modules) : base(settings, modules) { }
public override IEnumerable<IBinding> GetBindings(Type service)
{
var bindings = base.GetBindings(service);
if (bindings.Count() > 1)
{
bindings = bindings.Where(c => !c.Service.IsGenericTypeDefinition);
}
return bindings;
}
}
Комментарии:
1. Я использовал этот же подход, хотя я уточнил оператор if, чтобы сначала убедиться, что существует одна нестандартная привязка к сервису
Ответ №3:
public class ExtendedNinjectKernal : StandardKernel
{
public ExtendedNinjectKernal(params INinjectModule[] modules) : base(modules) { }
public ExtendedNinjectKernal(INinjectSettings settings, params INinjectModule[] modules) : base(settings, modules) { }
public override IEnumerable<IBinding> GetBindings(Type service)
{
var bindings = base.GetBindings(service);
//If there are multiple bindings, select the one where the service does not have generic parameters
if (bindings.Count() > 1 amp;amp; bindings.Any(a => !a.Service.IsGenericTypeDefinition))
bindings = bindings.Where(c => !c.Service.IsGenericTypeDefinition);
return bindings;
}
}