Search code examples
c#asp.net-mvcdependency-injectionasp.net-mvc-5unity-container

HttpContext.Current is null while trying to register types into IoC container


I am trying to setup IoC container in my ASP.NET MVC 5 application so I can access these objects anywhere in my application.

I choose to use Unity.Mvc container for the job.

During my type registration step, I am trying to run the following code

var httpContext = new HttpContextWrapper(HttpContext.Current);
container.RegisterInstance<HttpContextBase>(httpContext);

var sessionWrapper = new HttpSessionStateWrapper(HttpContext.Current.Session);
container.RegisterInstance<HttpSessionStateBase>(sessionWrapper);

var httpServerUtility = new HttpServerUtilityWrapper(HttpContext.Current.Server);
container.RegisterInstance<HttpServerUtilityBase>(httpServerUtility);

However, the line HttpContext.Current.Session is throwing a null exception as the HttpContext.Current object is null.

How can I correctly inject a non-null HttpContextWrapper instance into my IoC container?


Solution

  • How can I correctly inject a non-null HttpContextWrapper instance into my IoC container?

    These lines cover all 3 cases (HttpContext, HttpContext.Session, and HttpContext.Server):

    var httpContext = new HttpContextWrapper(HttpContext.Current);
    container.RegisterInstance<HttpContextBase>(httpContext);
    

    Since there are no sessions during application startup, you cannot access them this early in the MVC 5 Application Lifecycle.

    Once you have injected httpContext into a component, you can access the session state in the runtime part of the application.

    public class SomeService : ISomeService
    {
        private readonly HttpContextBase httpContext;
    
        public SomeService(HttpContextBase httpContext)
        {
            if (httpContext == null)
                throw new ArgumentNullException(nameof(httpContext));
            this.httpContext = httpContext;
            // Session state is still null here...
        }
    
        public void DoSomething()
        {
            // At runtime session state is available.
            var session = httpContext.Session;
        }
    }
    

    NOTE: It is generally not a good practice to make your services depend directly on session state. Instead, you should have the controller pass session state values through method parameters (i.e. DoSomething(sessionValue)), or alternatively implement a SessionStateAccessor wrapper around HttpContextBase that can be injected into your services, similar to how it is done in ASP.NET Core.