Adam Storr - Are you registering IHttpContextAccessor correctly?

Are you registering IHttpContextAccessor correctly?

Published on 23 January 2018

After starting to write a service in aspnetcore I needed to access the current HttpContext to get access to the current logged in user. Injecting HttpContext use to be very bad in previous versions of asp.net so I investigated how best to get access to items on it in the new world. This is where I discovered the IHttpContextAccessor interface and a whole new world opened up for me.

To register a dependency in aspnetcore you find the ConfigureServices method in your Startup class and add the interface with the concrete class. There are many different scopes available to register dependencies.

First iteration ...

public void ConfigureServices(IServiceCollection services)
{
	services.AddMvc();	
	services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();
}

Looked good for now however as aspnetcore is still relatively new to me I wanted to make sure this was registered correctly so I dug around the internet and found that you should register it as a Singleton!

So the above becomes ...

public void ConfigureServices(IServiceCollection services)
{
	services.AddMvc();
	services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}

While I was searching for best practices I found the HttpServiceCollectionExtensions class in the aspnet httpabstractions Github repo and this confirmed to me that it should be registered as a Singleton.

The extension method in the Github repo is ...

public static IServiceCollection AddHttpContextAccessor(this IServiceCollection services)
{
	if (services == null)
	{
		throw new ArgumentNullException(nameof(services));
	}

	services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
	return services;
}

It makes the ConfigureServices method cleaner and means the item is registered as expected by the framework.

public void ConfigureServices(IServiceCollection services)
{
	services.AddMvc();
	services.AddHttpContextAccessor();
}

Interestingly its only a recent addition to the code base and isn't in the released 2.0.1 Microsoft.AspNetCore.Http.Abstractions nuget package so it means I've stumbled upon an aspnetcore unreleased 2.1 addition, nice!

Any questions/comments then please contact me on Twitter @WestDiscGolf