Autofac не может разрешить перечислимые типизированные HttpClients - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть ряд служб, которые требуют использования типизированного HttpClient из HttpClientFactory. Хотя я могу разрешить одну службу, я не могу разрешить 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: ни один из конструкторов, найденных с 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' для типа 'ConsoleApp2.MyHttpClient', не может быть вызван с доступными службами и параметрами: Не удается разрешить параметр «System.Net.Http.HttpClient client» конструктора «Void .ctor (System.Net.Http.HttpClient)».

`` `

Проблема в том, что AddHttpClient добавляет собственную регистрацию IMyHttpClient. Но я хочу зарегистрироваться только с помощью Autofac! Есть ли способ использовать типизированные клиенты, но при этом оставаться с Autofac?

1 Ответ

0 голосов
/ 13 сентября 2018

Исключение объясняет, что 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>> возвращает перечисление с одним IMyHttpClient, которое инициализируется с HttpClient из ядра HttpClientFactory.

UPD: пост был обновлен комментарием @norekhov

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...