Использование инъекции свойств вместо инъекции конструктора
Короче говоря, я пытаюсь использовать ELMAH с MVC 2 и Ninject, и мне нужно использовать конструкторы без параметров. Я создал начальную запись об этом здесь: Использование конструктора без параметров без Ninject?
Мне было рекомендовано использовать инъекцию свойств вместо инъекции конструктора. Поэтому я перешел от этого:
public class DepartmentsController : Controller
{
private IDepartmentsRepository departmentsRepository;
public DepartmentsController(IDepartmentsRepository departmentsRepository)
{
this.departmentsRepository = departmentsRepository;
}
...
}
:
public class DepartmentsController : Controller
{
private IDepartmentsRepository _departmentsRepository;
[Inject]
public IDepartmentsRepository DepartmentsRepository
{
get { return _departmentsRepository; }
set { _departmentsRepository = value; }
}
...
}
Но в моих других функциях контроллера, пытаюсь ли я получить доступ к DepartmentsRepository или _departmentsRepository, я получаю ссылку на объект, не установленную на экземпляр объекта при попытке получить к нему доступ.
Есть ли что-то еще, что мне нужно сделать здесь?
Ответы
Ответ 1
У меня была аналогичная проблема. Посмотрите на мои вопросы: Использование Ninject с Membership.Provider.
В основном, когда вы инициализируете DepartmentsController
, вам нужно вставить this
(т.е. ваш департамент-контроллер в ваш ядро Ninject.Так что-то вроде:
public class DepartmentsController : Controller
{
private IDepartmentsRepository _departmentsRepository;
[Inject]
public IDepartmentsRepository DepartmentsRepository
{
get { return _departmentsRepository; }
set { _departmentsRepository = value; }
}
public DepartmentsController()
{
NinjectHelper.Kernel.Inject(this);
}
}
Где NinjectHelper в этом случае получает текущее ядро Ninject.
Ответ 2
Попробуйте что-то вроде этого:
Global.asax.cs
protected void Application_Start()
{
DependencyResolver.SetResolver(
new MyDependencyResolver(
new StandardKernel(
new MyModule())));
//...
}
MyDependencyResolver.cs
public class MyDependencyResolver : IDependencyResolver
{
private IKernel kernel;
public MyDependencyResolver(IKernel kernel)
{
this.kernel = kernel;
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
}
MyModule.cs
public class MyModule : NinjectModule
{
public override void Load()
{
Bind<IDepartmentsRepository>().To<DepartmentsRepository>();
}
}
Ответ 3
Могут существовать две причины исключения исключений объектов.
1) Ninject не знает, как привязать IDepartmentsRepository к конкретной реализации DepartmentsRepository (я сомневаюсь, что это так)
2) Если вы пытаетесь получить доступ к свойству DepartmentsRepository в своем конструкторе контроллера, он будет генерировать исключение (поскольку Ninject может только вводить зависимые свойства после создания объекта).
Надеюсь, что это поможет.
Ответ 4
Как сказал Дэниел Т. в вышеприведенном комментарии, вы должны проверить Ninject.Web.Mvc
. Если вы используете NinjectHttpApplication в этом проекте, он будет автоматически расшифровывать все для вас, так что когда NinjectControllerFactory создаст новый контроллер, он вызовет Inject(), чтобы вы могли заполнить инъекции свойств.