简体   繁体   English

将处理程序委托为 Transient 或 Singleton

[英]Delegating Handler as Transient or Singleton

We are using http client factory and delegating handler to invoke a partner api and process the response.我们正在使用 http 客户端工厂和委托处理程序来调用合作伙伴 api 并处理响应。 AuthenticationDelegating handler as shown below has a responsibility to get the required token for partner api authentication and provide it part of the api request.如下所示的 AuthenticationDelegating 处理程序有责任获取合作伙伴 api 身份验证所需的令牌,并将其作为 api 请求的一部分提供。

Question - Should i register AuthenticationDelegationHandler as Transient or Singleton if the token expiration is set to 24 hours?问题 - 如果令牌过期设置为 24 小时,我应该将 AuthenticationDelegationHandler 注册为 Transient 还是 Singleton?

startup.cs启动.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));

httpclient factory 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;
        }
    }

AuthenticationDelegatingHandler身份验证委托处理程序

 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;
        }
    }

Custom delegating handler must always be registered as transient dependencies.自定义委托处理程序必须始终注册为瞬态依赖项。 All the examples in the Microsoft documentation show that custom delegating handlers must be registered as transient dependencies. Microsoft 文档中的所有示例都表明自定义委托处理程序必须注册为瞬态依赖项。

This stackoverflow question and this article explain the reasons behind this.这个stackoverflow 问题这篇文章解释了这背后的原因。

To summarize: always register your custom delegating handlers with transient lifetime when you are using the ASP.NET core HTTP client factory .总结一下:当您使用 ASP.NET 核心 HTTP 客户端工厂时,请始终使用瞬态生命周期注册您的自定义委托处理程序

Notice that this guideline has nothing to do with your business logic to handle both the access token and its lifetime.请注意,此指南与处理访问令牌及其生命周期的业务逻辑无关。 It is a side effect of the way the ASP.NET core HTTP client factory handles the DI scope which uses to resolve dependencies (read the linked article for an in depth explanation).这是 ASP.NET 核心 HTTP 客户端工厂处理用于解析依赖项的 DI scope 的方式的副作用(阅读链接文章以获得深入解释)。

If you want to take some ideas about how to handle access tokens and their expiration by using a delegating handler, this project can offer you some insights.如果您想了解如何使用委派处理程序处理访问令牌及其过期,该项目可以为您提供一些见解。

The concept of token expired and HttpDelegationHandler is just quite un-relative.令牌过期和 HttpDelegationHandler 的概念完全不相关。 One that should stick with HttpRequestMessage and the other should stick with HttpClient .一个应该坚持使用HttpRequestMessage ,另一个应该坚持使用HttpClient

In short, you're trying to interact with the request, response in the exact time that the request was sent, which possibility can get an unauthorize response.简而言之,您正在尝试与请求进行交互,并在发送请求的确切时间进行响应,这可能会导致未授权响应。 That can be done right, but it's quite complicated.这可以正确完成,但它非常复杂。

Instead, why not just consider another approach?相反,为什么不考虑另一种方法呢? Like a background service that run every 30 mins, if your token expire in 3 hour or less, take a new token and store it either on cache or database?就像每 30 分钟运行一次的后台服务一样,如果您的令牌在 3 小时或更短时间内过期,是否获取一个新令牌并将其存储在缓存或数据库中? I think that just much more clean and easier than the way you're trying to solve the same problem.我认为这比您尝试解决相同问题的方式更简洁、更容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM