使用工厂方法创建类型化的HTTP客户端ASP.NET Core 2.1

时间:2019-02-08 23:21:51

标签: c# asp.net asp.net-core dependency-injection dotnet-httpclient

我正在遵循有关在我的应用程序中注册HTTP客户端的指南/文档。我需要打电话给几个服务,所以我决定使用“类型客户”。

为了调用另一个服务,我需要使用OAuth-因为这是服务到服务的调用,所以当我获得访问令牌时,我对其进行缓存+我已经设置了令牌的定期刷新。这意味着还有一个IAccessTokenCache组件,可为我提供服务的访问令牌。

我要弄清楚的是如何注册和配置键入的HTTP客户端,前提是它也依赖于IAccessTokenCache

我正在使用ASP.NET Core 2.1(重要细节,请继续阅读)。

HTTP客户端包装如下(来自:HttpClientFactory in ASP.NET Core 2.1 (Part 2) ):

public class ServiceFooClient
{
    public ServiceFooClient(HttpClient client)
    {
        Client = client;
    }

    public HttpClient Client { get; }
}

这是我注册和配置客户端的方式:

services
    .AddHttpClient<ServiceFooClient>(
        c =>
        {
            c.BaseAddress = new Uri("https://www.foo.svc");

            // TODO: grab particular access token from cache
            c.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "...");
        })
    .AddHttpMessageHandler<ResponseMonitorHandler>()
    .ConfigureHttpMessageHandlerBuilder(
        b =>
        {
            var handler =
                b.AdditionalHandlers.OfType<ResponseMonitorHandler>().FirstOrDefault();

            if (handler != null)
            {
                handler.ServiceName = "Foo Service";
            }
        });

...我已经在配置HTTP客户端,甚至添加了自定义HTTP处理程序。您可以看到我想访问IAccessTokenCache的确切点,但是我看不到。

我能想到的可能解决方案:

HttpClient包装器中配置基础ServiceFooClient,例如:

// ctor
public ServiceFooClient(HttpClient httpClient, IAccessTokenCache tokenCache)
{
    Client = httpClient;
    Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenCache.GetToken("Foo"));
}

这可以很好地工作,除非我不进行配置解耦-突然,专用的HTTP客户端在Startup中有一部分配置(基本URI,其他HTTP处理程序),在包装类中还有另一部分(设置授权标头)。

不使用AddHttpClient扩展方法(和其他方法)

我真的不需要打电话给HttpClientFactoryServiceCollectionExtensions.AddHttpClient<T>(...)-我可以自己做所有的事情。但是作为懒惰的开发人员……我什至不想结束这句话。里面有很多注册,所以对我来说这很重要。

升级到ASP.NET Core 2.2

与上一点有关-在2.1中,没有AddHttpClient(2.2:AddHttpClient<TClient>(this IServiceCollection services, Action<IServiceProvider, HttpClient> configureClient))的重载,它将接受服务提供者的回调。升级到2.2可能是最好的解决方案,但是我必须确保没有其他问题(并且我已经知道在HTTP上下文中获取/设置请求跟踪ID有BC中断)。这可能有潜在的风险,所以我首先尝试解决2.1范围内的问题。

将2.1的分支与2.2进行比较:HttpClientFactoryServiceCollectionExtensions

自定义HTTP处理程序设置请求标头

与我现在注册ResponseMonitorHandler的方式相同,我可以注册可以访问IAccessTokenCache并设置请求授权标头的HTTP处理程序。

但是同样,与第一种情况一样,这会取消HTTP客户端的配置。另外,如果我有几个不同的访问令牌,我要么需要实现几个HTTP处理程序,要么做一些逻辑来根据请求属性确定要使用的缓存中的令牌。

最后,问题:还有其他我没有考虑的方法吗?在ASP.NET 2.1中是否有简单的解决方案? (...当然只是2.2版中的复制粘贴方法)

1 个答案:

答案 0 :(得分:0)

显然,2.1 ConfigureHttpClient(IHttpClientBuilder, Action<IServiceProvider,HttpClient>)中还有另一种扩展方法,正是我所需要的!