将处理程序委托为瞬态或单例

Seh*_*Ram 3 c# asp.net-core

我们使用 http 客户端工厂和委托处理程序来调用合作伙伴 api 并处理响应。如下所示的 AuthenticationDelegating 处理程序有责任获取合作伙伴 api 身份验证所需的令牌并将其提供为 api 请求的一部分。

问题 - 如果令牌过期时间设置为 24 小时,我应该将 AuthenticationDelegationHandler 注册为 Transient 还是 Singleton?

启动.cs

        services.AddTransient<AuthenticationDelegatingHandler>();
        var apiSettings = Configuration.GetSection(nameof(APIParameters)).Get<APIParameters>();
        var apRegistrationParameters = Configuration.GetSection(nameof(AppRegistrationParameters)).Get<AppRegistrationParameters>();

        services.AddHttpClient("ApiSecuredClient", client =>
        {
            client.BaseAddress = new Uri(ApiSettings.BaseUrl);
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(ApiSettings.MediaType));
           
        })
        .AddHttpMessageHandler<AuthenticationDelegatingHandler>().SetHandlerLifetime(TimeSpan.FromMinutes(apRegistrationParameters.LifetimeOfAuthenticationHandlerInMinutes));
Run Code Online (Sandbox Code Playgroud)

http客户端工厂

   public virtual async Task<HttpResponseMessage> GetRequestAsync<T>(T req,                                                                            Sales360APIParameters 
 _paramenters) where T : class, IApiBaseRequest
    {
        using (var client = _httpClientFactory.CreateClient("XXXClient"))
        {
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(_paramenters.MediaType));
            var json = JsonConvert.SerializeObject(req);
            var data = new StringContent(json, Encoding.UTF8, _paramenters.MediaType);
            data.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("version", _paramenters.Version));
            HttpResponseMessage Res = await client.PostAsync(_paramenters.API, data);
            return Res;
        }
    }
Run Code Online (Sandbox Code Playgroud)

认证委托处理程序

 public class AuthenticationDelegatingHandler : DelegatingHandler
 {
    private AppRegistrationParameters _appRegistrationInfo;
    private DateTime _tokenExpirationLocalTime;
    private ILogger<AuthenticationDelegatingHandler> _logger;
    public AuthenticationDelegatingHandler(ILogger<AuthenticationDelegatingHandler> logger, IConfiguration config)
    {
        _appRegistrationInfo = config.GetSection(nameof(AppRegistrationParameters)).Get<AppRegistrationParameters>();
        _logger = logger;

    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        try
        {
            Task<HttpResponseMessage> response = null;
            if (_tokenExpirationLocalTime != null && _tokenExpirationLocalTime > DateTime.Now.AddSeconds(_appRegistrationInfo.TimeoutRequestInSeconds))
            {
                response = ProcessRequest(request);

                if (response.Result.StatusCode == HttpStatusCode.Unauthorized || response.Result.StatusCode == HttpStatusCode.Forbidden)
                    response = ProcessRequest(request, true);
            }
            else
            {
                response = ProcessRequest(request, true);
            }

            return response.Result;
        }
        catch (Exception ex)
        {
            _logger.LogError("{systemId} - Error Authenticating with App. {errorCode} for " + request.Content, Constants.SystemId, Constants.ErrorCode3100);
            _logger.LogError(ex.Message);
            throw;
        }
    }
Run Code Online (Sandbox Code Playgroud)

Enr*_*one 9

自定义委托处理程序必须始终注册为临时依赖项。Microsoft 文档中的所有示例都表明自定义委托处理程序必须注册为瞬态依赖项。

这个stackoverflow 问题这篇文章解释了这背后的原因。

总结一下:当您使用 ASP.NET core HTTP 客户端工厂时,请始终注册具有瞬态生命周期的自定义委托处理程序

请注意,此准则与处理访问令牌及其生命周期的业务逻辑无关。这是 ASP.NET core HTTP 客户端工厂处理用于解析依赖项的 DI 范围的方式的副作用(请阅读链接文章以获取深入说明)。

如果您想了解如何使用委托处理程序处理访问令牌及其过期,该项目可以为您提供一些见解。