HttpClient的多种实现

Multiple implementation of HttpClient

场景:

I need to load work items from two project management systems (VSTS and Jira) through their REST API. Each of them has different authorization mechanism:

  • VSTS: Using access token that load from database, varied by team/group of users
  • Jira: Using personal token that load from user claims, varied by user

基本类和界面:

public interface IProjectManagementClient
{
    ProjectManagementType Type { get; }
    Task<WorkItem> GetWorkItemAsync(ProjectManagement projectManagement, int id, CancellationToken token = default(CancellationToken));
    Task<List<WorkItem>> GetAllWorkItemsAsync(ProjectManagement projectManagement, string term, int limit = 10, CancellationToken token = default(CancellationToken));
}

public enum ProjectManagementType
{
    VSTS,
    Jira
}

public class ProjectManagement
{
    public int Id { get; set; }
    public ProjectManagementType Type { get; set; }
    public string BaseAddress { get; set; }
    public string AccessToken { get; set; }
}

设置:

services.AddHttpClient<IProjectManagementClient, VstsClient>();
services.AddHttpClient<IProjectManagementClient, JiraClient>()
    .AddHttpMessageHandler(provider => new BasicAuthHandler(provider.GetService<IHttpContextAccessor>(), CustomClaimTypes.TrackerToken));

用法示例:

public TimesheetsController(IEnumerable<IProjectManagementClient> projectManagementClients)
{
    _projectManagementClients = projectManagementClients;
}

public void DoWork()
{
    foreach (var timesheet in _timesheets)
    {
        var projectManagementClient = _projectManagementClients.First(o => o.Type == timesheet.ProjectManagement.Type);
        timesheet.WorkItem = timesheet.WorkItemId.HasValue
            ? await projectManagementClient.GetWorkItemAsync(timesheet.ProjectManagement, timesheet.WorkItemId.Value, token)
            : null;
    }
}

问题:

Even though I've only registered the BasicAuthHandler to the JiraClient. It has been applied to both VSTS and Jira clients.

Thus it has overridden the VSTS authorization that has been set previously in VstsClient.

如果我一次只设置和使用它们,两者都可以正常工作。请帮忙。

JiraClientVstsClient 覆盖,因为它们都注册在相同的(空)名称上,这是默认的。尝试使用命名注册:

services.AddHttpClient<IProjectManagementClient, VstsClient>("VSTS");
services.AddHttpClient<IProjectManagementClient, JiraClient>("JIRA")
    .AddHttpMessageHandler(provider => new BasicAuthHandler(
        provider.GetService<IHttpContextAccessor>(),
        CustomClaimTypes.TrackerToken));

在这种情况下 IEnumerable<IProjectManagementClient> 应该给出两个项目,配置如上,没有覆盖。