如何在 ASP.NET Core 1.0 的 DI 中的 Startup 类中添加 IHttpContextAccessor?

Posted

技术标签:

【中文标题】如何在 ASP.NET Core 1.0 的 DI 中的 Startup 类中添加 IHttpContextAccessor?【英文标题】:How to add IHttpContextAccessor in the Startup class in the DI in ASP.NET Core 1.0? 【发布时间】:2016-11-06 04:16:21 【问题描述】:

在 ASP.NET Core RC 1 中,我使用以下代码检索上下文的值(页面的完整地址)。然后我在配置中记录了这个值。

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();
        );
        
   

现在我开始在 ASP.NET Core 1.0 上更新项目。但在网站启动期间,我收到以下错误:

System.InvalidOperationException 无法解析类型的服务 'Microsoft.AspNetCore.Http.IHttpContextAccessor' 尝试 激活“MyProject.Startup”。

在 Microsoft.Extensions.Internal.ConstructorMatcher.CreateInstance(IServiceProvider 提供者)在 Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider 提供者,类型 instanceType,Object[] 参数)在 Microsoft.Extensions.Internal.ActivatorUtilities.GetServiceOrCreateInstance(IServiceProvider 提供者,类型类型)在 Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetServiceOrCreateInstance(IServiceProvider 提供者,类型类型)在 Microsoft.AspNetCore.Hosting.Internal.StartupLoader.LoadMethods(IServiceProvider 服务,类型 startupType,字符串 environmentName)在 Microsoft.AspNetCore.Hosting.c__DisplayClass1_0.b__1(IServiceProvider sp) 在 Microsoft.Extensions.DependencyInjection.ServiceLookup.FactoryService.Invoke(ServiceProvider 提供者)在 Microsoft.Extensions.DependencyInjection.ScopedCallSite.Invoke(ServiceProvider 提供者)在 Microsoft.Extensions.DependencyInjection.SingletonCallSite.Invoke(ServiceProvider 提供者)在 Microsoft.Extensions.DependencyInjection.c__DisplayClass12_0.b__0(ServiceProvider 提供者)在 Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(类型 服务类型)在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider 提供者,类型 serviceType) 在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider 提供者)在 Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureStartup() 在 Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices() 在 Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

.NET Framework X64 v4.0.30319.42000 | Microsoft.AspNetCore.Hosting 版本 1.0.0-rtm-21431 |微软视窗 6.1.7601 S

应用启动时如何获取新版本的IHttpContextAccessor?

【问题讨论】:

如果您查看 .Net Core 的重大更改,您会发现默认情况下不再注册 IHttpContextAccessor。 github.com/aspnet/Hosting/issues/793 【参考方案1】:

它不再是默认服务。您必须在 Startup.cs 中配置它

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

更新:在 ASP.NET Core 2.1 中,添加了 the AddHttpContextAccessor helper extension method 以使用正确的生命周期(单例)正确注册 IHttpContextAccessor。所以,在 ASP.NET Core 2.1 及以上版本中,代码应该是

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

来源:https://github.com/aspnet/Hosting/issues/793

【讨论】:

官宣:github.com/aspnet/Announcements/issues/190 一个问题不应该是AddTransient,因为它是针对请求的? @Ruchan 你有没有得到这个答案?它应该是单例的还是瞬态的? @Reft 我用过单例。这是有关此github.com/aspnet/Hosting/issues/793 的更多信息,请阅读 davidfowl 的答案 @Ruchan 将IHttpContextAccessor 注册为单例是可行的,因为它使用AsyncLocal&lt;T&gt; 来存储HttpContext。【参考方案2】:

你可以这样添加。

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

【讨论】:

【参考方案3】:

.Net 6 可以这样添加

builder.Services.AddSingleton();

【讨论】:

以上是关于如何在 ASP.NET Core 1.0 的 DI 中的 Startup 类中添加 IHttpContextAccessor?的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)

Asp.NET Core 一个接口的多个实现如何通过 DI 注册?

ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)

带有 ASP.NET Core DI 的 MediatR

如何在 asp.net core 1.0 中查看当前 url

ASP.NET Core 依赖注入(DI)