【问题标题】:Resolve service in HttpContext configure Action在 HttpContext 中解析服务 configure Action
【发布时间】:2018-11-08 12:34:05
【问题描述】:

在 asp.net 核心中,我正在注册键入 HttpClient,我需要来自服务提供商的解析服务。我如何解决那里的服务?

例子:

services
    .AddHttpClient<TTypedHttpClient, TTypedHttpClientImpl>(httpClient =>
    {
        // how to resolve service on next line?
        var config = RESOLVE_SERVICE<IConfig>();
        httpClient.BaseAddress = config.GetBaseUrl();
    });

【问题讨论】:

  • 您是在问如何在 Startup 类的 ConfigureServices 方法中访问配置?为什么要提到 action 和 HttpContext?
  • 不,IConfig 在这里是指在服务提供者中注册的一般服务。
  • 那些注册在ConfigureServices方法中,与HttpContext或Action无关。
  • 哦,我明白了。我所说的动作并不是指 MVC 控制器动作。我的意思是AddHttpClient 方法的参数。配置HttpClient的是动作(匿名方法)。
  • 有一个重载,但您可能应该只使用配置 DTO,而不是在请求新 HttpClient 时检索设置的服务。

标签: .net asp.net-core dependency-injection .net-core dotnet-httpclient


【解决方案1】:

我认为实际问题是在注册类型化的 HttpClient 和 HttpContext(特定 HTTP 请求的上下文)时如何访问配置或任何其他服务不相关。

更新在 .NET Core 2.1 中,AddHttpClient 没有 两个 类型参数和 aIServiceCollection 的重载,尽管文档显示。通过在 AddHttpClient 之后调用 ConfigureHttpClient 来执行相同的工作。

services
    .AddHttpClient<TTypedHttpClient, TTypedHttpClientImpl>()
    .ConfigureHttpClient(svc,httpClient =>
    {
        // how to resolve service on next line?
        var config = svc.GetRequiredService<IConfig>();
        httpClient.BaseAddress = config.GetBaseUrl();
    });

原创

您可以使用AddHttpClient(IServiceCollection, String, Action< IServiceProvider,HttpClient>) 重载将IServiceProvider 传递给可用于解析其他服务的操作:

services
    .AddHttpClient<TTypedHttpClient, TTypedHttpClientImpl>((svc,httpClient =>
    {
        // how to resolve service on next line?
        var config = svc.GetRequiredService<IConfig>();
        httpClient.BaseAddress = config.GetBaseUrl();
    });

我建议阅读 Steve Gordon 关于类型化 HttpClients 和 HttpClientFactory 的系列文章。 Using Typed Clients from Singleton Services 展示了如何使用 AddHttpClient 来配置客户端。他的其余文章展示了如何使用 HttpClientFactory 和 Polly 对其进行配置以进行正确的池化和重试

配置

Steve Gordon 的示例使用 IOption 从配置基础架构中读取数据。

services.AddHttpClient<IConfigurationService, ConfigurationService>()
.ConfigureHttpClient((serviceProvider, client) =>
{
    var baseAddress = serviceProvider.GetRequiredService<IOptions<SdkOptions>>().Value.BaseAddress;
    client.BaseAddress = new Uri(baseAddress);
});

这是一个的想法 - HttpClient 注册不应该知道也不应该依赖于其配置值的来源。 IConfig 应该只是在配置阶段加载的配置 DTO。

.NET Core 配置可以从 json/xml/ini 文件、数据库、外部服务、环境变量以及任何可以以 "section:subsection" - value 形式返回值的东西加载值。它还允许组合和重载设置,这非常很有用。

我的应用程序从文件(基本配置)、其他团队管理的数据库(外部服务端点和凭据)和命令行(可能的覆盖)加载设置。端点配置用于创建 N 个命名的 HttpClient,每个端点一个。我使用 this example 创建了一个加载端点设置的 EF Core 提供程序。

这也允许在应用程序启动时验证设置,这可能是一个显着的好处。没有它,应用程序在第一次请求特定的 HttpClient 之前不会知道有什么问题。

【讨论】:

  • 谢谢。我一直在寻找重载(答案的第一部分),但即使它在 .NET Core 2.1 的文档中,它也不存在于代码中(github.com/aspnet/HttpClientFactory/blob/release/2.1/src/…)。它已经在 .NET Core 2.2 发布分支中,但现在处于预览阶段。 ConfigureHttpClient 扩展在 .NET Core 2.1 中,所以我可以使用它。
  • @MartinVolek 它有一个重载,接受一个类型参数但不接受两个
  • 是的,现在我知道了。而且单个参数重载不足以满足我的目的(这就是我发布问题的原因)。
猜你喜欢
  • 1970-01-01
  • 2013-02-01
  • 2020-12-18
  • 2021-08-19
  • 1970-01-01
  • 1970-01-01
  • 2019-05-17
  • 1970-01-01
  • 2013-12-18
相关资源
最近更新 更多