Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to get current Unity container inside controller

I registered unity container like this:

    var container = new UnityContainer();

    container.RegisterType<ICacheManager, CacheManager>(new ContainerControlledLifetimeManager())

Is it possible to get access to this "container" from controller

like image 485
Sergey Avatar asked Nov 05 '12 11:11

Sergey


4 Answers

Not sure why you need that, but here's the code:

public ActionResult Area51()
    {
        var _service = DependencyResolver.Current.GetService(typeof (IDummyService));

        return View();
    }

If what you are trying to do is injecting a Controller, you should set DepedencyResolver to use your IoC container in Global.asax's application start. Then, MVC will inject dependency to your controller automatically.

var container = new UnityContainer();
DependencyResolver.SetResolver(new Unity.Mvc4.UnityDependencyResolver(container));

Look here for more example:

http://www.dotnet-tricks.com/Tutorial/dependencyinjection/632V140413-Dependency-Injection-in-ASP.NET-MVC-4-using-Unity-IoC-Container.html

like image 127
stack247 Avatar answered Sep 18 '22 15:09

stack247


I'm assuming you're resolving some Controller instance using the container. If that's the case, you can have the controller receive the IUnityContainer as a dependency just like any other.

What are you trying to accomplish? Getting the container in your resolved classes is not great because it couples your classes with the container, and can usually be replaced with other mechanisms.

class Program
{
    static void Main(string[] args)
    {
        var container = new UnityContainer();

        var foo = container.Resolve<MyController>();
    }
}

public class MyController
{
    private IUnityContainer container;

    public MyController(IUnityContainer container)
    {
        this.container = container;
    }
}
like image 32
fsimonazzi Avatar answered Sep 20 '22 15:09

fsimonazzi


One way of doing this which I often do for convenience is to declare your container as a global variable in your Global.ascx.cs file like:

public class MvcApplication : System.Web.HttpApplication
{
    public static UnityContainer Container;

    protected void Application_Start()
    {
         // assuming your initialize here
    } 
}

However this is fairly hack-ish.

The correct thing to do would be to use Unity to resolve your Controllers (See this article on creating a unity controller factory), and then allow unity to inject any dependencies into your controller when it resolves the controller.

So a controller like:

public MyController: Controller {

 public ICacheManager CacheManager {get;set;}

}

Would automagically resolver any dependencies that your container has registered.

like image 36
shenku Avatar answered Sep 19 '22 15:09

shenku


Although it is possible to that, it's best that you avoid it.

It's best that you take any dependencies the controller needs via constructor parameters. This way, the class (controller) makes it clear what are the dependencies required for it to run.

If configured correctly, the container will provide those dependencies and their dependencies (if any), and so on.

The usage of an IoC container should typically be restricted to only one place inside an application (called the composition root). Any extra reference/call to the container is susceptible to lead to the Service Locator anti-pattern. See the linked article for reasons why such an approach may be bad.

like image 41
Cristian Lupascu Avatar answered Sep 18 '22 15:09

Cristian Lupascu