10

我的问题如下:我有一个名为 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 很陌生,所以也许我做错了什么。

谢谢,阿米。

4

4 回答 4

21

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

于 2009-06-17T14:48:41.873 回答
0

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

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

于 2009-06-17T14:37:46.870 回答
0

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

于 2009-06-17T14:39:23.530 回答
0

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

于 2009-11-21T06:42:18.330 回答