ConfigureServices 中的 AddHttpContextAccessor 与每个 HttpClient
AddHttpContextAccessor in ConfigureServices vs per HttpClient
在 ConfigureServices 方法中添加一次 httpContextAccessor 与为每个配置的 HttpClient 添加 HttpContextAccessor 之间有什么区别吗?
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
// FIRST VERSION
services.AddHttpContextAccessor();
// SECOND VERSION
var myService1 = services.AddHttpClient<TestHttpClient1>(c =>
{
c.BaseAddress = new Uri(Configuration["TestHttpClient1"]);
});
myService1.Services.AddHttpContextAccessor();
var myService2 = services.AddHttpClient<TestHttpClient2>(c =>
{
c.BaseAddress = new Uri(Configuration["TestHttpClient2"]);
});
myService2.Services.AddHttpContextAccessor();
}
我的猜测是认为在第二个版本中,我们有两个单例,一个用于 class TestHttpClient1,另一个用于 TestHttpClient2,但我不明白为什么要这样做,因为我看到此代码正在生产中。
Is there any difference between adding the httpContextAccessor one time in ConfigureServices method versus adding the HttpContextAccessor per HttpClient configured.
不,没有任何区别。 myService1.Services
和 myService2.Services
都引用 相同的 IServiceCollection
作为 services
变量。第一次调用 (services.AddHttpContextAccessor()
) 将注册服务,但接下来的两次调用 (myService1.Services.AddHttpContextAccessor()
和 myService2.Services.AddHttpContextAccessor()
) 将 no-op(什么都不做).
为了将所有这些都放在上下文中,这里是 AddHttpClient<TClient>(...)
(source) 的源代码摘录:
var builder = new DefaultHttpClientBuilder(services, name);
// ...
return builder;
创建了一个新的DefaultHttpClientBuilder
实例,它包裹了传入的IServiceCollection
。因为这是一个扩展方法,所以这里的services
指的是同一个services
和你的 ConfigureServices
方法一样。然后通过 IHttpClientBuilder.Services
公开,这就是您在引用时使用的内容,例如myService1.Services
.
对 AddHttpContextAccessor
的调用使用 TryAddSingleton
,只有在服务尚未注册时才会注册该服务 (source):
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
在您的示例中,它 已经在第一次调用 services.AddHttpContextAccessor()
时被注册,这意味着接下来的两次注册尝试什么都不做。
在 ConfigureServices 方法中添加一次 httpContextAccessor 与为每个配置的 HttpClient 添加 HttpContextAccessor 之间有什么区别吗?
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
// FIRST VERSION
services.AddHttpContextAccessor();
// SECOND VERSION
var myService1 = services.AddHttpClient<TestHttpClient1>(c =>
{
c.BaseAddress = new Uri(Configuration["TestHttpClient1"]);
});
myService1.Services.AddHttpContextAccessor();
var myService2 = services.AddHttpClient<TestHttpClient2>(c =>
{
c.BaseAddress = new Uri(Configuration["TestHttpClient2"]);
});
myService2.Services.AddHttpContextAccessor();
}
我的猜测是认为在第二个版本中,我们有两个单例,一个用于 class TestHttpClient1,另一个用于 TestHttpClient2,但我不明白为什么要这样做,因为我看到此代码正在生产中。
Is there any difference between adding the httpContextAccessor one time in ConfigureServices method versus adding the HttpContextAccessor per HttpClient configured.
不,没有任何区别。 myService1.Services
和 myService2.Services
都引用 相同的 IServiceCollection
作为 services
变量。第一次调用 (services.AddHttpContextAccessor()
) 将注册服务,但接下来的两次调用 (myService1.Services.AddHttpContextAccessor()
和 myService2.Services.AddHttpContextAccessor()
) 将 no-op(什么都不做).
为了将所有这些都放在上下文中,这里是 AddHttpClient<TClient>(...)
(source) 的源代码摘录:
var builder = new DefaultHttpClientBuilder(services, name);
// ...
return builder;
创建了一个新的DefaultHttpClientBuilder
实例,它包裹了传入的IServiceCollection
。因为这是一个扩展方法,所以这里的services
指的是同一个services
和你的 ConfigureServices
方法一样。然后通过 IHttpClientBuilder.Services
公开,这就是您在引用时使用的内容,例如myService1.Services
.
对 AddHttpContextAccessor
的调用使用 TryAddSingleton
,只有在服务尚未注册时才会注册该服务 (source):
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
在您的示例中,它 已经在第一次调用 services.AddHttpContextAccessor()
时被注册,这意味着接下来的两次注册尝试什么都不做。