C# ASP.NET核心DI:向HTTP客户端提供异步基址
每当客户机向我的ASP.NET Core 3.1 API发出请求时,我都希望使用C# ASP.NET核心DI:向HTTP客户端提供异步基址,c#,asp.net-core,dependency-injection,factory-pattern,C#,Asp.net Core,Dependency Injection,Factory Pattern,每当客户机向我的ASP.NET Core 3.1 API发出请求时,我都希望使用HttpClient在其他服务中执行一些操作 我使用依赖项注入注册了HttpClient: services.AddHttpClient(); 不幸的是,这个HttpClient的BaseAddress不是静态的。相反,客户端发送一个自定义头,其中包含对数据库条目的引用。 因此,为了确定HttpClient的基地址,我需要对数据库进行异步调用 目前我做了如下工作: 公共类控制器 { 公共SomeController
HttpClient
在其他服务中执行一些操作
我使用依赖项注入注册了HttpClient:
services.AddHttpClient();
不幸的是,这个HttpClient
的BaseAddress
不是静态的。相反,客户端发送一个自定义头,其中包含对数据库条目的引用。
因此,为了确定HttpClient的基地址
,我需要对数据库进行异步调用
目前我做了如下工作:
公共类控制器
{
公共SomeController(MyHttp、AddressRepository db)
{
_http=http;
_db=db;
}
公共异步任务SomeAction([FromRoute]字符串id)
{
var address=wait _db.Get(id);
_http.BaseAddress=新Uri(地址);
var res=await_http.GetAsync(“某些路径”);
//处理响应并执行一些业务逻辑
返回新的{};
}
}
这是可行的,但每当我在任何服务中使用MyHttp
时,我都需要确保该服务设置BaseAddress
属性。我宁愿将地址作为构造函数参数提供。 首先,我想到了工厂实现。但是
services.AddScoped(serviceProvider=>{})
不支持异步操作(我知道对象初始化应该快速可靠)
但我觉得我目前的解决方案也是一种糟糕的做法。有没有更好的方法可以做到这一点?没错,服务集合注册不支持异步工厂,因为服务解析应该总是快速的 但是在客户端创建之后初始化
基地址
并没有什么错。因此,如果您想确保使用正确的基址初始化httpClient
,那么将该逻辑提取到单独的类中,以构建您的http客户机配置如何
public YourHttpClientFactory {
private IHttpClientFactory _factory;
public YourHttpClientFactory(IHttpClientFactory factory)
{
_factory = factory;
}
public Task<HttpClient> Create(Guid id) {
var client = factory.createClient();
// do your async client initialization
return client;
}
}
publicYourHttpClientFactory{
私营IHttpClientFactory\u工厂;
public YourHttpClientFactory(IHttpClient工厂)
{
_工厂=工厂;
}
公共任务创建(Guid id){
var client=factory.createClient();
//执行异步客户端初始化
返回客户;
}
}
您可以添加一个委托处理程序,并在Send方法中添加您的逻辑,该方法是异步的。在AddHttpClient调用之上添加处理程序还有其他扩展方法。Tho不知道如何与基本地址一起工作感谢您的回复。但是有了这样的解决方案,我无法想象如何通过依赖注入来实现这一点。因为在一个作用域(用户请求)中,将有多个服务使用此上下文(此作用域的一个特定基址)。如果所有这些服务都使用HttpFactory.Create()
,我会有很多实例。我说的请求范围内的所有服务都应该使用相同的baseAddress
对吗?如果是这样,您可以在自定义中间件中执行baseAddress
初始化,例如注册一个命名的http客户端,在中间件中解析它并根据请求信息执行初始化,那么管道中的所有服务稍后将使用预配置的httpclient。