Ninject не обязательный объект в BaseController в MVC3 - PullRequest
1 голос
/ 10 ноября 2010

Я только что обновил свой проект MVC2 до MVC3 и использовал ссылку на пакет библиотеки NuGet для установки ninject. Это создало класс appstart, и я использовал следующий код для внедрения моего класса IMembershipService.

public static void RegisterServices(IKernel kernel) {
        kernel.Bind<IMembershipService>().To<AccountMembershipService>();
    }

Это прекрасно работает с моим HomeController, например.

public class HomeController : Controller
{
    public IMembershipService MembershipService { get; set; }

    public HomeController() : this(null) { }

    public HomeController(IMembershipService service)
    {
        MembershipService = service;
    }

ОДНАКО, я использую BaseController. Почти тот же код в базовом классе больше не работает.

public class BaseController : Controller
{
    public IMembershipService MembershipService { get; set; }
    public UserService UserService { get; set; }

    public BaseController() : this(null, null) { }

    public BaseController(IMembershipService service, UserService userService)
    {
        MembershipService = service;
        UserService = userService ?? new UserService();
    }

Если я сломаюсь в конструкторе базового контроллера, сервис будет просто NULL. Я никогда не использовал Ninject для IOC, поэтому, возможно, ответ очевиден, но почему он не внедрит мой AccountMembershipController в базовый класс, как я этого хочу? Я не вижу, что отличается, хотя я понимаю, что дополнительный уровень наследования может как-то портить Ninject.

Ответы [ 2 ]

5 голосов
/ 10 ноября 2010

Ваши устройства HomeController от контроллера, а не от BaseController? Кроме того, у вас есть конструктор по умолчанию для BaseController, который устанавливает все как ноль. Зачем тебе это вообще? Я бы начал с избавления от конструкторов по умолчанию. Вам не нужно никаких конструкторов по умолчанию.

1 голос
/ 10 ноября 2010

Я столкнулся с этой же проблемой сам.Предполагая, что ваш код выглядит следующим образом:

public HomeController : BaseController
{

}

public BaseController : Controller
{
    public IMembershipService MembershipService { get; set; }

    public MembershipService() { }

    public MembershipService(IMembershipService service)
    {
        MembershipService = service;
    }
}

По какой-то причине Ninject считает, что HomeController имеет только один конструктор, по умолчанию без параметров.Когда вы помещаете все в HomeController, он может найти инжектируемый конструктор, но разложить его на базовый класс, и по какой-то причине он не будет смотреть в базовом классе, чтобы увидеть, есть ли перегруженные конструкторы.Для этого есть два исправления:

  1. Удалить конструктор по умолчанию.Это мое предпочтительное решение, потому что оно вынуждает инжектировать конструктор (например, когда вы создаете контроллер вручную при модульном тестировании), но недостатком является то, что вам нужно реализовать конструктор во всех ваших подклассах.
  2. Сохраните конструктор по умолчанию, но добавьте атрибут [Inject] ко всем вашим внедряемым свойствам:

    public BaseController : Controller
    {
        [Inject] public IMembershipService MembershipService { get;set; }
        // rest is the same
    }
    

Ninject правильно введет свойства таким образом, но имейте в виду, что Ninject будетвызовите конструктор без параметров.

...