Использование инъекции свойств вместо инъекции конструктора

Короче говоря, я пытаюсь использовать 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(), чтобы вы могли заполнить инъекции свойств.