【问题标题】:Autofac fails to resolve enumerable of typed HttpClientsAutofac 无法解析可枚举的类型化 HttpClients
【发布时间】:2019-10-23 00:10:31
【问题描述】:

我有许多服务需要使用来自 HttpClientFactory 的类型化 HttpClient。 虽然我可以解析一项服务,但我无法解析这项服务的 IEnumerable。

interface IMyHttpClient
{
}

class MyHttpClient: IMyHttpClient
{
    public MyHttpClient(HttpClient client)
    {
    }
}

class Program
{
    static void Main(string[] args)
    {
        var services = new ServiceCollection();
        services.AddHttpClient()
                .AddHttpClient<IMyHttpClient, MyHttpClient>();

        var builder = new ContainerBuilder();
        // Exception goes away when remove this line
        builder.RegisterType<MyHttpClient>().As<IMyHttpClient>();
        builder.Populate(services);
        var provider = builder.Build();

        // ============== This works
        // provider.Resolve<IMyHttpClient>();

        // ============== This throws exception
        provider.Resolve<IEnumerable<IMyHttpClient>>();
    }
}

构造函数将被调用一次,然后抛出异常:

``` DependencyResolutionException:无法使用可用的服务和参数调用类型为“ConsoleApp2.MyHttpClient”的“Autofac.Core.Activators.Reflection.DefaultConstructorFinder”的构造函数: 无法解析构造函数“Void .ctor(System.Net.Http.HttpClient)”的参数“System.Net.Http.HttpClient 客户端”。

```

问题是 AddHttpClient 添加了它自己的 IMyHttpClient 注册。但我只想使用 Autofac 注册!有没有办法使用类型化客户端但仍然使用 Autofac?

【问题讨论】:

    标签: autofac httpclientfactory


    【解决方案1】:

    异常说明 Autofac 无法解析参数“System.Net.Http.HttpClient 客户端”。我想这是因为此类类型未在您的容器中注册以进行IMyHttpClient 的第二次注册。为了节省HttpClientFactory 的优势,您可以注册显式构造函数参数,例如:

    static void Main(string[] args)
    {
        var services = new ServiceCollection();
        services.AddHttpClient();
    
        var builder = new ContainerBuilder();
        // exclicit resolving client for constructor
        builder.RegisterType<MyHttpClient>().As<IMyHttpClient>().WithParameter(
            (p, ctx) => p.ParameterType == typeof(HttpClient), 
            (p, ctx) => ctx.Resolve<IHttpClientFactory>().CreateClient());
    
        builder.Populate(services);
        var provider = builder.Build();
    
        // ============== This works
        provider.Resolve<IMyHttpClient>();
    
        // ============== This works too
        provider.Resolve<IEnumerable<IMyHttpClient>>();
    }
    

    在此示例中,Resolve&lt;IEnumerable&lt;IMyHttpClient&gt;&gt; 返回带有单个 IMyHttpClient 的枚举,该枚举由核心 HttpClientFactory 中的 HttpClient 初始化。

    UPD:帖子由@norekhov 评论更新

    【讨论】:

    • 是的,这正是我的想法。我不会在 ServiceCollection 域中注册多个客户端,而是仅将 .AddHttpClient 放在那里,而不是直接在 Autofac 注册中解析参数。 services.AddHttpClient&lt;IMyHttpClient, MyHttpClient&gt;(); 可以替换为 services.AddHttpClient(); 仅用于基本注册。
    • 如果您只需要使用核心 HttpClientFactory 解析 HttpClient 实例,是的,它会为您工作。
    • 更新答案以防止重复注册IMyHttpClient
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-19
    • 1970-01-01
    • 2012-08-05
    • 1970-01-01
    • 2012-04-03
    • 1970-01-01
    相关资源
    最近更新 更多