1

ASP NET Core 2.1 为我们提供了 HttpClientFactory,这是构建自定义 httpClients 的好方法。

我们将此方法与注入到 startup.cs 类的构造函数中的端点配置服务一起使用。

代码看起来有点像:

        public Startup(IConfiguration configuration, IEndpointService endpointService)
        {
            Configuration = configuration;
            _endpointService = endpointService;
        }

        public void ConfigureServices(IServiceCollection services)
        {
           foreach(var endpoint in _endpointService)
           {
              services.AddHttpClient(endpoint.name, c => {
                 c.BaseAddress = endpoint.Address;
                 // plus other config as required
              });
           }
        }

IEndpointService 是在 Startup 被注入以下调用之前配置的。

    IWebHostBuilder webHostBuilder =
        WebHost.CreateDefaultBuilder(args)
            .ConfigureServices((webHostBuilderContext, services) => {
                services.AddSingleton<IEndpointService, EndpointService>();
            })
            .UseStartup<Startup>();

这允许我们从外部数据源读取信息并配置多个具有不同配置的命名 httpClients。

此功能已在 ASP NET Core 3.0 中删除。

请参阅:https ://weblogs.thinktecture.com/pawel/2017/08/aspnet-core-beware-singleton-may-not-be-singleton.html和https://andrewlock.net/avoiding-startup-service-注入-asp-net-core-3/

这给我们留下了一个问题,如何最好地在 3.0 中实现相同的功能。

这是迄今为止我想出的最好的,但我很想知道关于这个问题的指导是什么。

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<IEndpointService, EndpointService>();

            using (var serviceProvider = services.BuildServiceProvider())
            {
                var endpointService = serviceProvider.GetService<IEndpointService>();

                foreach (var endpointConfiguration in endpointService.GetEndpointConfiguration())
                {
                    // Create a named client and any other configuration that we need to do here.
                    services.AddHttpClient(endpointConfiguration.Name, client =>
                    {
                        client.BaseAddress = endpointConfiguration.BaseAddress;

                        // Add any extra config that is required here
                    });
                }
            }
        }

在此示例中,我使用 serviceProvider.GetService 强制创建 EndpointService。

我意识到我可能已经重新创建了多个单例错误(请参阅上面的链接),但我不确定这里的最佳方法。

想法?

4

1 回答 1

1

如果EndpointService没有依赖项,则只需在构建主机时创建一个实例,并ConfigureServices在主机构建器上的便捷方法中使用它

IEndpointService endpointService = new EndpointService();
IWebHostBuilder webHostBuilder =
    WebHost.CreateDefaultBuilder(args)
        .ConfigureServices((webHostBuilderContext, services) => {
            foreach(var endpoint in endpointService.GetEndpointConfiguration()) {
                services.AddHttpClient(endpoint.name, c => {
                    c.BaseAddress = endpoint.Address;
                    // plus other config as required
                });
            }
        })
        .UseStartup<Startup>();//<--if this is still actually needed.
于 2019-12-05T11:36:25.967 回答