简体   繁体   中英

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. 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.

AFAIK, Unity will only resolve public properties. 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. 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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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