Unity【依赖】注入与继承

发布于 2024-07-25 00:09:17 字数 1761 浏览 5 评论 0原文

我的问题如下: 我有一个名为 ApplicationController 的基本控制器(ASP.Net MVC 控制器),我希望所有控制器都继承它。 该基本控制器有一个 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 很陌生,所以也许我做错了什么。

谢谢, 阿米。

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. this base controller has a ILogger property, marked with a [Dependency] attribute. (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.

what am I doing wrong? why doesn't the container resolves the base class dependencies when creating the derived controller?

code samples:


ApplicationController:

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

}

derived 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:

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:

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.

thanks,
Ami.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你与昨日 2024-08-01 00:09:17

AFAIK,Unity 只会解析公共属性。 因此,您受保护的财产将不会得到解决。

AFAIK, Unity will only resolve public properties. Therefore your protected property will not be resolved.

橙幽之幻 2024-08-01 00:09:17

我不确定这是否相关,但通常,我避免使用同名的命名空间和类(在您的例子中为 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();
    }
}

的都一样。 代码看起来没问题。

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. But that may be not the problem.

I'm also not sure if the [Dependency] attribute works for derived types. 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. The code looks ok.

悟红尘 2024-08-01 00:09:17

我对统一也相当缺乏经验,但我认为你需要向 contsaner 注册你的 HomeController,而不是记录器。

I'm fairly unexperienced with unity as well, but I think you need to register your HomeController with the contsaner, not the logger.

转瞬即逝 2024-08-01 00:09:17

我遇到了同样的问题,并通过将 ILogger 更改为公共来解决它。 这是 VS2010、.NET 4 中的 ASP.NET MVC2 项目。从逻辑上讲,这是有道理的,因为 Unity 没有创建代理类或任何东西,它只是设置它有权访问的属性,并且有一个映射 -因此仅限公开。

I had the same issue, and fixed it by changing the ILogger to public. 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文