Использование внедрения свойств вместо внедрения конструктора - PullRequest
11 голосов
/ 02 февраля 2011

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

Есть ли что-то еще, что мне нужно сделать здесь?

Ответы [ 4 ]

11 голосов
/ 02 февраля 2011

У меня была похожая проблема. Посмотрите на мои вопросы: Использование 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.

3 голосов
/ 02 февраля 2011

Попробуйте что-то вроде этого:

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>();
        }
    }
2 голосов
/ 02 февраля 2011

Может быть две причины для ссылки на объект, а не для установленного исключения.

1) Ninject не знает, как привязать IDepartmentsRepository к конкретной реализации DepartmentsRepository (хотя я сомневаюсь, что это так)

2) Если вы пытаетесь получить доступ к свойству DepartmentsRepository в конструкторе вашего контроллера, оно сгенерирует исключение (поскольку Ninject может вводить зависимости свойств только после создания объекта).

Надеюсь, что это поможет.

0 голосов
/ 04 февраля 2011

Как написал Дэниел Т. в вышеприведенном комментарии, вы должны проверить Ninject.Web.Mvc.Если вы используете NinjectHttpApplication в этом проекте, он будет автоматически связывать все за вас, поэтому, когда NinjectControllerFactory создаст новый контроллер, он вызовет Inject (), чтобы заполнить инъекции свойства.

...