Search code examples
c#asp.net-mvcdependency-injectionunity-container

Is there any alternative to storing the DI container reference in Application variable?


I have an C# MVC application. I am using Unity Container to resolve my dependencies. For injecting dependencies inside MVC controller, I am using constructor injection. To achieve this I have replaced the MVC Controller Builder factory with my Controller Builder factory on Application_Start event i.e.

protected void Application_Start() 
{    
 IUnityContainer container = new UnityContainer();

 //All container registrations ....

ControllerBuilder.Current.SetControllerFactory(new 
UnityControllerFactory(container)); 

//Store reference of container in application object
HttpContext.Current.Application["Injector"] = container;   
}

However I need instance of container to resolve dependencies at certain places where it is not possible to do constructor injection, for e.g. Application_AuthenticateRequest event. So as a fallback, I have stored a reference to the container in the Application object. I used this instance to resolve references.

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
 var container = HttpContext.Current.Application["Injector"] as 
 IUnityContainer;
 var service = container.Resolve<IService>();
}

Is it ok to store the container reference in application variable or is there any other recommended practice ? I also know there is Property Injection. Can I use it in this scenario?


Solution

  • You should strive to prevent access to the container from within application code. Within the Composition Root however, it is typically okay to access the container directly, and it is often impossible to prevent this anyway. Your Application_AuthenticateRequest can be considered part of your Composition Root, so it is fine to access the container (and there is really no way around it).

    You can however simplify the code to the following:

    private static IUnityContainer container;
    
    protected void Application_Start() 
    {    
        container = new UnityContainer();
    
        ...
    }
    
    protected void Application_AuthenticateRequest(object sender, EventArgs e)
    {
        var service = container.Resolve<IService>();
    }