10

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.

3
  • Does this work for application controller? Commented Jun 17, 2009 at 14:30
  • Did you get this to ever work? My code is almost identical and I cannot get the base controller to resolve either. Anybody? Commented Sep 3, 2009 at 21:05
  • Ray - it worked after making the properties public. that's a price you have to pay in order to get Unity working. Commented Sep 4, 2009 at 7:26

4 Answers 4

21

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

Sign up to request clarification or add additional context in comments.

1 Comment

OK, Jakob gets 2 points :) changing the property to public solved the problem. the Unity container resolved the dependency and all is well.
0

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.

Comments

0

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

1 Comment

It is correct to register the logger because you want to inject your dependency (an ILogger implementation).
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.