我有以下接口和类(为简洁起见,省略了实现):
public interface ITokenAuthenticationService { ... }
public class TokenAuthenticationService(
IOptions<TokenOptions> options,
HttpClient httpClient,
TimeProvider? timeProvider = null
) : ITokenAuthenticationService
{ ... }
public class TokenDelegatingHandler(
ITokenAuthenticationService tokenAuthenticationService
) : DelegatingHandler
{ ... }
public class MyService1(HttpClient client)
{ ... }
在我的程序中:
var sp = new ServiceCollection()
.Configure<TokenOptions>(configuration.GetRequiredSection("Service1"))
.AddTransient<TokenDelegatingHandler>()
.AddHttpClient<ITokenAuthenticationService, TokenAuthenticationService>()
.ConfigureHttpClient(c => c.BaseAddress = new Uri("http://auth.service1.com")).Services
// Service 1
.AddHttpClient<MyService1>()
.ConfigureHttpClient(c => c.BaseAddress = new Uri("http://service1.com"))
.AddHttpMessageHandler<TokenDelegatingHandler>().Services
.BuildServiceProvider();
var bar = sp.GetRequiredService<MyService1>();
var result = await bar.DoSomethingAsync("baz");
TokenAuthenticationService
需要一些选项才能正常工作。现在:
我该如何设置,以便我可以使用第二个服务 (
MyService2
) 来使用另一个 TokenDelegatingHandler
,并为第二个服务设置不同的设置?我不确定如何将正确的 TokenDelegatingHandler
关联到正确的 HttpClient (无需继承 TokenDelegatingHandler 并制作 Service1TokenDelegatingHandler
和 Service2TokenDelegatingHandler
或其他东西)。
由于不同的
TokenAuthenticationService
、TokenOptions
和 HttpClient
实例可以以不同的设置共存,因此您需要一个键控/命名设置。
由于您使用的是 .NET 8 - 您的代码显示了主构造函数的用法 - 您可以使用以下组合:
由于所有MyService1
实例都具有类似的配置,因此您可以将其设置为类型化 HTTP 客户端。 但对于它的
TokenDelegatingHandler
,你需要一个键控/命名的检索。
services.AddHttpClient<MyService1>()
.ConfigureHttpClient(o => o.BaseAddress = new Uri("http://service1.com"))
.AddHttpMessageHandler(
sp => new TokenDelegatingHandler(
sp.GetRequiredKeyedService<ITokenAuthenticationService>("service1-tokenhandler")
));
使用已知密钥将 TokenDelegatingHandler
注册为
MyService1
。
services.AddKeyedTransient<ITokenAuthenticationService, TokenAuthenticationService>(
"service1-tokenhandler",
(sp, key) => new TokenAuthenticationService(
sp.GetRequiredService<IOptionsMonitor<TokenOptions>>().Get("tokenservice1-options"),
sp.GetRequiredService<IHttpClientFactory>().CreateClient("tokenservice1-client"),
sp.GetRequiredService<TimeProvider>()
));
对其设置/选项和HttpClient
进行类似的操作。
services.AddHttpClient("tokenservice1-client")
.ConfigureHttpClient(o => o.BaseAddress = new Uri("http://auth.service1.com"));
services.Configure<TokenOptions>("tokenservice1-options",
configuration.GetSection("tokenservice1-options-section"));
设置文件(例如Appsettings.json
)应包含带有
tokenservice1-options-section
路径/键的部分。