How to add IHttpContextAccessor in the Startup class in the DI in ASP.NET Core 1.0?

Kolya_Net picture Kolya_Net · Jul 4, 2016 · Viewed 41.6k times · Source

In ASP.NET Core RC 1 I used the following code to retrieve the value of context (full address of the page). Then I recorded this value in the configuration.

public class Startup
{
        public IConfigurationRoot Configuration { get; set; }
        private IHostingEnvironment CurrentEnvironment { get; set; }
        private IHttpContextAccessor HttpContextAccessor { get; set; }
        public Startup(IHostingEnvironment env,
                IHttpContextAccessor httpContextAccessor)
            {                
                var builder = new ConfigurationBuilder()
                    .SetBasePath(env.ContentRootPath)
                    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
    
                if (env.IsDevelopment())
                {
                    builder.AddUserSecrets();
                }
                builder.AddEnvironmentVariables();
                Configuration = builder.Build();
                CurrentEnvironment = env;
                HttpContextAccessor = httpContextAccessor;
            }
        public void ConfigureServices(IServiceCollection services)
        {
        ...
        
        services.AddOptions();
        services.Configure<WebAppSettings>(configuration);
        services.Configure<WebAppSettings>(settings =>
        {
            ...
            settings.WebRootPath = CurrentEnvironment.WebRootPath;
            settings.DomainUrl = HttpContextAccessor.HttpContext.Request.Host.ToUriComponent();
        });
        }
   }

Now I started to update the project on ASP.NET Core 1.0. But during the launch of the site I get the following error:

System.InvalidOperationException Unable to resolve service for type 'Microsoft.AspNetCore.Http.IHttpContextAccessor' while attempting to activate 'MyProject.Startup'.

at Microsoft.Extensions.Internal.ConstructorMatcher.CreateInstance(IServiceProvider provider) at Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters) at Microsoft.Extensions.Internal.ActivatorUtilities.GetServiceOrCreateInstance(IServiceProvider provider, Type type) at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetServiceOrCreateInstance(IServiceProvider provider, Type type) at Microsoft.AspNetCore.Hosting.Internal.StartupLoader.LoadMethods(IServiceProvider services, Type startupType, string environmentName) at Microsoft.AspNetCore.Hosting.<>c__DisplayClass1_0.b__1(IServiceProvider sp) at Microsoft.Extensions.DependencyInjection.ServiceLookup.FactoryService.Invoke(ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ScopedCallSite.Invoke(ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.SingletonCallSite.Invoke(ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.<>c__DisplayClass12_0.b__0(ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider) at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureStartup() at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices() at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

.NET Framework X64 v4.0.30319.42000 | Microsoft.AspNetCore.Hosting version 1.0.0-rtm-21431 | Microsoft Windows 6.1.7601 S

How do I get the new version IHttpContextAccessor during application startup?

Answer

Oleksandr Fentsyk picture Oleksandr Fentsyk · Jul 4, 2016

It is no longer a default service. You have to configure it in Startup.cs

services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();

UPDATE: In ASP.NET Core 2.1, the AddHttpContextAccessor helper extension method was added to correctly register the IHttpContextAccessor with the correct lifetime (singleton). So, in ASP.NET Core 2.1 and above, the code should be

services.AddHttpContextAccessor();
services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();

Source: https://github.com/aspnet/Hosting/issues/793