Unity [зависимость] инъекция и наследование - PullRequest
10 голосов
/ 17 июня 2009

Мой вопрос таков: У меня есть базовый контроллер (контроллер ASP.Net MVC) под названием ApplicationController, и я хочу, чтобы все мои контроллеры наследовали от него. этот базовый контроллер имеет свойство ILogger, помеченное атрибутом [Dependency]. (да, я знаю, что должен использовать инжектор конструктора, мне просто любопытно этот атрибут).

Я создал контейнер, зарегистрировал типы, изменил фабрику по умолчанию, все в порядке. проблема в том, что когда я пытаюсь использовать свое свойство Logger в производном контроллере, оно не разрешается.

что я делаю не так? почему контейнер не разрешает зависимости базового класса при создании производного контроллера?

образцы кода:


ApplicationController:

public class ApplicationController : Controller
{
    [Dependency]
    protected ILogger _logger { get; set; }

}

производный контроллер:

public class HomeController : ApplicationController
{
    public HomeController()
    {

    }
    public ActionResult Index()
    {
        _logger.Log("Home controller constructor started.");
        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        return View();
    }

    public ActionResult About()
    {
        return View();
    }
}

Фабрика контроллеров Unity:

public class UnityControllerFactory : DefaultControllerFactory
{
    private readonly IUnityContainer _container;
    public UnityControllerFactory(IUnityContainer container)
    {
        _container = container;
    }

    protected override IController GetControllerInstance(Type controllerType)
    {
        return _container.Resolve(controllerType) as IController;
    }
}

Пример Global.asax.cs:

protected void Application_Start()
    {
        _container = new UnityContainer();
        _container.RegisterType<ILogger, Logger.Logger>();
        UnityControllerFactory factory = new UnityControllerFactory(_container);
        ControllerBuilder.Current.SetControllerFactory(factory);

        RegisterRoutes(RouteTable.Routes);
    }

Я довольно новичок в Unity, поэтому, возможно, я сделал что-то не так.

спасибо, Ами.

Ответы [ 4 ]

19 голосов
/ 17 июня 2009

AFAIK, Unity разрешает только общедоступные свойства. Поэтому ваше охраняемое имущество не будет разрешено.

0 голосов
/ 21 ноября 2009

У меня была та же проблема, и я исправил ее, изменив ILogger на public. Это относится к проекту ASP.NET MVC2 в VS2010, .NET 4. Это логично, поскольку Unity не создает прокси-класс или что-либо еще, а просто устанавливает свойства, к которым у него есть доступ, и имеет отображение для - следовательно, только для общественности.

0 голосов
/ 17 июня 2009

Я тоже не очень разбираюсь с Unity, но я думаю, что вам нужно зарегистрировать ваш HomeController с помощью contsaner, а не регистратора.

0 голосов
/ 17 июня 2009

Я не уверен, связано ли это с этим, но обычно я избегаю иметь пространства имен и классы с одинаковыми именами (в вашем случае, Logger.Logger), потому что у меня были проблемы с этим в прошлом. Но это может быть не проблема.

Я также не уверен, что атрибут [Dependency] работает для производных типов. Если вы измените это для инжектора конструктора, это все еще не работает? Что-то вроде:

public class ApplicationController : Controller
{
    protected ILogger _logger { get; set; }


    public ApplicationController(ILogger logger)
    {
         this._logger = logger;

    }
}

и

public class HomeController : ApplicationController
{
    public HomeController(ILogger logger) : base(logger)
    {

    }
    public ActionResult Index()
    {
        _logger.Log("Home controller constructor started.");
        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        return View();
    }

    public ActionResult About()
    {
        return View();
    }
}

а остальное точно так же. Код выглядит нормально.

...