简体   繁体   English

unity [dependency]注入和Inheritance

[英]Unity [dependency] injection and Inheritance

My question is as follows: I have a base controller (ASP.Net MVC controller) called ApplicationController, and I want all my controller to inherit from it.我的问题如下:我有一个名为 ApplicationController 的基础 controller(ASP.Net MVC 控制器),我希望我所有的 controller 都继承自它。 this base controller has a ILogger property, marked with a [Dependency] attribute.这个基础 controller 有一个 ILogger 属性,标有 [Dependency] 属性。 (yes, I know I should use constructor injection, I'm just curious about this attribute). (是的,我知道我应该使用构造函数注入,我只是对这个属性感到好奇)。

I created the container, registered types, changed the default factory, everything is fine.我创建了容器,注册了类型,更改了默认工厂,一切都很好。 the problem is that when I try to use my Logger property in the derived controller, it's not resolved.问题是,当我尝试在派生的 controller 中使用我的 Logger 属性时,它没有得到解决。

what am I doing wrong?我究竟做错了什么? why doesn't the container resolves the base class dependencies when creating the derived controller?为什么容器在创建派生 controller 时不解析基础 class 依赖项?

code samples:代码示例:


ApplicationController:应用控制器:

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

}

derived controller:派生 controller:

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 controller factory: Unity controller 工厂:

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 sample: 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);
    }

I'm quite new to Unity, so maybe I did something wrong.我对 Unity 很陌生,所以也许我做错了什么。

thanks, Ami.谢谢,阿米。

AFAIK, Unity will only resolve public properties. AFAIK,Unity 只会解析公共属性。 Therefore your protected property will not be resolved.因此,您的受保护财产将不会得到解决。

I'm not sure if this is related, but usually, I avoid having namespaces and classes with the same name (in your case, Logger.Logger), for I had problems with this in the past.我不确定这是否相关,但通常情况下,我会避免使用同名的名称空间和类(在您的情况下为 Logger.Logger),因为我过去曾遇到过这个问题。 But that may be not the problem.但这可能不是问题所在。

I'm also not sure if the [Dependency] attribute works for derived types.我也不确定 [Dependency] 属性是否适用于派生类型。 If you change it for constructor injection, does this still not work?如果改成构造函数注入,这还不行吗? Something like:就像是:

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


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

    }
}

and

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();
    }
}

and the rest just the same.和 rest 一样。 The code looks ok.代码看起来没问题。

I'm fairly unexperienced with unity as well, but I think you need to register your HomeController with the contsaner, not the logger.我对 unity 也不太熟悉,但我认为你需要用 contsaner 注册你的 HomeController,而不是记录器。

I had the same issue, and fixed it by changing the ILogger to public.我有同样的问题,并通过将 ILogger 更改为公共来修复它。 This is with an ASP.NET MVC2 project in VS2010, .NET 4. It makes sense, logically, since Unity isn't creating a proxy class or anything, it's just setting properties that it has access to, and has a mapping for - hence public only.这是 VS2010 中的一个 ASP.NET MVC2 项目,.NET 4. 从逻辑上讲,这是有道理的,因为 Unity 没有创建代理 class 或任何东西,它只是设置它可以访问的属性,并有一个映射 - 因此只公开.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM