【问题标题】:How do I inject IHttpClientFactory in my Azure Service Fabric application?如何在我的 Azure Service Fabric 应用程序中注入 IHttpClientFactory?
【发布时间】:2019-08-01 23:32:15
【问题描述】:

我正在尝试在我的解决方案中使用IHttpClientFactory 而不仅仅是HttpClient 的实例。

startup.cs:

services.AddHttpClient("Test", client =>
{
    client.BaseAddress = new Uri("http://localhost:57863");
    client.Timeout = new TimeSpan(0, 0, 30);
    client.DefaultRequestHeaders.Clear();
});

在我的服务中需要一个 HttpClient:

private readonly Uri _clusterLinuxUri;
private readonly IHttpClientFactory _clientFactory;
public LiasseService(ConfigSettings settings, IHttpClientFactory clientFactory)
{
    _clusterLinuxUri = new Uri($"{settings.LinuxClusterEndpoint}");
    _clientFactory = clientFactory;
}
public async Task<LiasseDetails> CreateLiasseAsync(LiasseCreate liasseData)
{
    using (var response = await _clientFactory.CreateClient("Test")
        .PostAsJsonAsync($"{_clusterLinuxUri}{_createPath}", liasseData))
    {
        await response.CheckHttpError($"{nameof(CreateLiasseAsync)} - error in CL");
        var detailsList = await response.Content.ReadAsAsync<LiasseDetailsList>();
        return detailsList.Details.FirstOrDefault();
    }
}

我还没弄清楚的部分是如何在Autofac中注入它。

程序.cs

    private static void Main()
    {
        try
        {
            var builder = new ContainerBuilder();
            builder.RegisterModule(new GlobalAutofacModule());
            builder.RegisterServiceFabricSupport();
            builder.RegisterStatelessService<FacadeCore>("xxx.FacadeCoreType");

            using (builder.Build())
            {
                ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(FacadeCore).Name);
                Thread.Sleep(Timeout.Infinite);
            }
        }
        catch (Exception e)
        {
            ServiceEventSource.Current.ServiceHostInitializationFailed(e.ToString());
            throw;
        }
    }


    public class GlobalAutofacModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterType<ConfigSettings>();

            builder.RegisterType<PaymentService>().As<IPaymentService>();
            builder.RegisterType<MailerService>().As<IMailerService>();
            builder.RegisterType<LiasseService>().As<ILiasseService>();
            builder.RegisterType<AnalyseFinanciereService>().As<IAnalyseFinanciereService>();
            builder.RegisterType<ApimService>().As<IApimService>();

            builder.RegisterType<UserRepository>().As<IUserRepository>();
            builder.RegisterType<ApplicationProcessRepository>().As<IApplicationProcessRepository>();
            builder.RegisterType<LiasseRepository>().As<ILiasseRepository>();

            builder.RegisterType<CustomUserIdProvider>().As<IUserIdProvider>();
        }
    }

我是否应该创建一些自定义客户端来实现IHttpClientFactory 以便能够注入它?我该怎么做?有什么例子吗?谢谢。

【问题讨论】:

    标签: c# autofac azure-service-fabric asp.net-core-2.2


    【解决方案1】:

    请在此处查看Interface documentation

    所以回答你的问题:

    1) 使用来自“ConfigureServices”方法的IServiceCollection 调用.AddHttpClient()

    2) 创建新的 Autofac 容器构建器并使用上面提到的IServiceCollection 填充它

    3) 从ConfigureServices 方法返回新的AutofacServiceProvider

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
       ...
    
       services.AddHttpClient();
    
       var containerBuilder = new ContainerBuilder();
    
       containerBuilder.Populate(services);
    
       var container = containerBuilder.Build();
    
       return new AutofacServiceProvider(container);
    }
    

    附: 确保添加 - Autofac.Extensions.DependencyInjection nuget 包,以便能够使用AutofacServiceProvider 类。

    【讨论】:

    • 不幸的是,我在服务结构的上下文中,containerbuilder 在我的 api 的 program.cs 中,而 configureservices 在我的 startup.cs 中
    • 可能是我很久以前的第一次尝试,可能没有奏效,因为我通常先尝试最简单的方法,不过我不记得了;)
    • 据我了解 FacadeCore 是无状态的,或者可能是有状态的服务,您使用 webhostBuilder 并注册启动类。我的建议是将所有类型的依赖项注册逻辑移至“启动”类。所有这些与 SF 相关的东西只是为了让您的服务运行,而听起来很愚蠢的“启动”就是启动(准备)您的应用程序:)
    【解决方案2】:

    除了使用基于 WebHostBuilder 的解决方案(类似于您在创建 vanilla Asp.Net Core Service Fabric 项目时获得的解决方案)之外,您也可以这样做

    public class HttpClientModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            
            builder.Register(_ =>
                {
                    var services = new ServiceCollection();
                    services.AddHttpClient();
                    var containerBuilder = new ContainerBuilder();
                    containerBuilder.Populate(services);
                    var container = containerBuilder.Build();
                    return new AutofacServiceProvider(container);
                })
                .As<IServiceProvider>()
                .SingleInstance();
    
    
            builder.Register(ctx =>
            {
                var scope = ctx.Resolve<IComponentContext>();
                var provider = scope.Resolve<IServiceProvider>();
                var factory = provider.GetService<IHttpClientFactory>();
                return factory.CreateClient();
            }).As<HttpClient>();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-09-30
      • 2018-02-22
      • 2019-05-10
      • 2016-03-21
      • 2016-09-11
      • 1970-01-01
      • 1970-01-01
      • 2017-02-10
      • 1970-01-01
      相关资源
      最近更新 更多