繁体   English   中英

使用 AddHttpClient 时如何配置其他依赖

[英]How to configure other dependencies when using AddHttpClient

我正在使用 AddHttpClient 根据 Microsoft 文档中的最佳实践来注入 HttpClient(使用Typed clients ),但是这种方法不允许我配置我的服务依赖项的 rest。

假设我有这个设置:

    public interface ISerializer { /*...*/ }

    public class Serializer : ISerializer { 

        private readonly string _options;

        public Serializer(string options) 
        {
            _options = options;
        }
        
        /*...*/
    }

    public class ServiceA
    {
        private readonly HttpClient _client;
        private readonly ISerializer _serializer;

        public ServiceA(HttpClient httpClient, ISerializer serializer)
        {
            _client = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
            _serializer = serializer ?? throw new ArgumentNullException(nameof(serializer));
        }

        public string MakeCall()
        {
            // var body = _serializer.Serialize();
            return _client.GetAsync("").Result.StatusCode.ToString();
        }
    }

    public class ServiceB { 
        /*
          Similar to ServiceA
        */ 
    }

    public static class ServiceCollectionExtensions
    {
        public static IServiceCollection AddServiceAandB(this IServiceCollection services)
        {            
            /* 
               If I do this below, Serializer("option 1") will be used in Services A and B
               however, what I would like is to have different Serializer's configurations for A and B (see full question below) 
            */
            services.AddTransient<ISerializer>((p) => new Serializer("option 1"));
            
            services.AddHttpClient<ServiceA>(c =>
            {
                c.BaseAddress = new Uri("api-url-for-A");
                c.Timeout = TimeSpan.FromSeconds(5);
            });

            services.AddHttpClient<ServiceB>(c =>
            {
                c.BaseAddress = new Uri("api-url-for-B");
                c.Timeout = TimeSpan.FromSeconds(5);
            });

            return services;
        }
    }

问题:如何使用 Serializer("option 1") 为 ServiceA 和 Serializer("option 2") 为 ServiceB 配置 ISerializer 依赖关系? 但是,因为我使用的是 AddHttpClient 并且它自己负责构建 ServiceA 和 ServiceB,所以我无法根据需要对其进行配置。

注意:如建议的那样,创建多个实现可能适用于简单的情况,但假设 Serializer 接收选项 object 并且为所有选项组合创建不同的实现是不可能的。 这就是为什么我想在 DI 设置期间配置选项。

任何帮助将不胜感激。

-------- 更新 1 --------

我不打算注入两个 ISerializer,而是能够配置 Serializer 并在构造 ServiceA 和 ServiceB 的同时利用.AddHttpClient。

例如(下面的代码是不可能的,但很理想):

services.AddHttpClient<ServiceA>(c =>
{
    c.BaseAddress = new Uri("api-url-for-A");
    c.Timeout = TimeSpan.FromSeconds(5);
});
services.AddTransient<ServiceA>(p => {
    return new ServiceA(p.GetHttpClientFor<ServiceA>(), new Serializer("option 1"));
});

services.AddHttpClient<ServiceB>(c =>
{
    c.BaseAddress = new Uri("api-url-for-B");
    c.Timeout = TimeSpan.FromSeconds(5);
});
services.AddTransient<ServiceB>(p => {
    return new ServiceB(p.GetHttpClientFor<ServiceB>(), new Serializer("option 2"));
});

// neither IServiceProvider.GetHttpClient method exists, nor I can use .AddHttpClient with AddTransient for same dependency.

如果串行器有多个选项,请引入 class,它将根据所需选项构建新的串行器。

public class SerializerBuilder
{
    private string _option;

    public SerializerBuilder With(string option)
    {
        _option = option;
    }

    public ISerializer Create()
    {
        return new Serializer(_option);
    }
}

public class ServiceA
{
    public ServiceA(HttpClient client, SerializerBuilder builder)
    {
        _serializer = builder.With("option A").Create();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM