Autofac fails to resolve enumerable of typed HttpClients

大兔子大兔子 提交于 2020-01-25 00:31:24

问题


I have a number of services which require usage of typed HttpClient from HttpClientFactory. Though I can resolve one service I can't resolve IEnumerable of this services.

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>>();
    }
}

Constructor will be called once and than exception is thrown:

``` DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'ConsoleApp2.MyHttpClient' can be invoked with the available services and parameters: Cannot resolve parameter 'System.Net.Http.HttpClient client' of constructor 'Void .ctor(System.Net.Http.HttpClient)'.

```

The issue is that AddHttpClient adds it's own registration of IMyHttpClient. But I do want to register using Autofac only! Is there a way to use typed clients but still stay with Autofac?


回答1:


The exception explains that Autofac can't resolve parameter 'System.Net.Http.HttpClient client'. I suppose this is because such type wasn't registered in your container for second resgistration of IMyHttpClient. To save an advantages of HttpClientFactory you can register excplicit constructor parameter for example like this:

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>>();
}

In this example Resolve<IEnumerable<IMyHttpClient>> return enumeration with single IMyHttpClient, that is initialized with HttpClient from core HttpClientFactory.

UPD: the post was updated by @norekhov comment



来源:https://stackoverflow.com/questions/52291150/autofac-fails-to-resolve-enumerable-of-typed-httpclients

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!