【问题标题】:Unity [dependency] injection and Inheritanceunity【依赖】注入和继承
【发布时间】:2009-06-17 14:15:30
【问题描述】:

我的问题如下: 我有一个名为 ApplicationController 的基本控制器(ASP.Net MVC 控制器),我希望我的所有控制器都继承自它。这个基本控制器有一个 ILogger 属性,用 [Dependency] 属性标记。 (是的,我知道我应该使用构造函数注入,我只是对这个属性感到好奇)。

我创建了容器,注册了类型,更改了默认工厂,一切都很好。问题是当我尝试在派生控制器中使用我的 Logger 属性时,它没有得到解决。

我做错了什么?为什么容器在创建派生控制器时不解析基类依赖?

代码示例:


应用控制器:

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 还很陌生,所以也许我做错了什么。

谢谢, 阿米。

【问题讨论】:

  • 这适用于应用程序控制器吗?
  • 你让它工作了吗?我的代码几乎相同,我也无法让基本控制器解析。有人吗?
  • Ray - 在公开属性后它起作用了。这是为了让 Unity 正常工作必须付出的代价。

标签: c# inheritance dependency-injection unity-container


【解决方案1】:

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

【讨论】:

  • 好的,Jakob 得到 2 分 :) 将属性更改为 public 解决了问题。 Unity 容器解决了依赖关系,一切都很好。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 注册logger是正确的,因为你想注入你的依赖(一个ILogger实现)。
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 2011-12-24
      • 2021-04-16
      • 1970-01-01
      • 1970-01-01
      • 2017-05-24
      相关资源
      最近更新 更多