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
.
如果我一次只设置和使用它们,两者都可以正常工作。请帮忙。
JiraClient
被 VstsClient
覆盖,因为它们都注册在相同的(空)名称上,这是默认的。尝试使用命名注册:
services.AddHttpClient<IProjectManagementClient, VstsClient>("VSTS");
services.AddHttpClient<IProjectManagementClient, JiraClient>("JIRA")
.AddHttpMessageHandler(provider => new BasicAuthHandler(
provider.GetService<IHttpContextAccessor>(),
CustomClaimTypes.TrackerToken));
在这种情况下 IEnumerable<IProjectManagementClient>
应该给出两个项目,配置如上,没有覆盖。
场景:
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 theJiraClient
. It has been applied to both VSTS and Jira clients.Thus it has overridden the VSTS authorization that has been set previously in
VstsClient
.
如果我一次只设置和使用它们,两者都可以正常工作。请帮忙。
JiraClient
被 VstsClient
覆盖,因为它们都注册在相同的(空)名称上,这是默认的。尝试使用命名注册:
services.AddHttpClient<IProjectManagementClient, VstsClient>("VSTS");
services.AddHttpClient<IProjectManagementClient, JiraClient>("JIRA")
.AddHttpMessageHandler(provider => new BasicAuthHandler(
provider.GetService<IHttpContextAccessor>(),
CustomClaimTypes.TrackerToken));
在这种情况下 IEnumerable<IProjectManagementClient>
应该给出两个项目,配置如上,没有覆盖。