Autofac 无法解析可枚举类型的 HttpClient

Autofac fails to resolve enumerable of typed HttpClients

我有许多服务需要使用来自 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' 找到的构造函数的 None: 无法解析构造函数 'Void .ctor(System.Net.Http.HttpClient)' 的参数 'System.Net.Http.HttpClient client'。

```

问题是 AddHttpClient 添加了它自己的 IMyHttpClient 注册。但我确实只想使用 Autofac 进行注册!有没有一种方法可以使用类型化的客户端,但仍然使用 Autofac?

异常说明 Autofac 无法解析参数 'System.Net.Http.HttpClient client'。我想这是因为这种类型没有在您的容器中注册 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<IEnumerable<IMyHttpClient>> return 具有单个 IMyHttpClient 的枚举,使用来自核心 HttpClientFactory 的 HttpClient 初始化。

更新:post 由@norekhov 评论更新