Общий хостинг с пользовательским DI пытается получить неправильный тип - PullRequest
0 голосов
/ 23 апреля 2019

Я использую универсальный хостинг в .NET Core, и я создал IHostedService, который создается в моем универсальном хосте следующим образом:

IHostBuilder builder = new HostBuilder()
    .ConfigureServices((hostBuilderContext, services) => {
        services.AddHostedService<MyService>();
     });

Где MyService - просто скелет:

public class MyService : IHostedService {
    public async Task StartAsync(CancellationToken cancellationToken) { }
    public async Task StopAsync(CancellationToken cancellationToken) { }
}

Это прекрасно работает.

Однако, если я попытаюсь использовать пользовательский DI вместо Microsoft.Extensions.DependencyInjection, AddHostedService() запросит IHost вместо IHostedService. Я вижу, что это происходит путем отладки пользовательского IServiceProvider:

public class MyCustomProvider : IServiceProvider {

    SomeContainer _someContainer;

    public MyCustomProvider(SomeContainer someContainer) {
        _container = container;
    }
    public object GetService(Type serviceType) {
        return _container.Get(serviceType);
        // This is only called once, and serviceType is typeof(IHost)
    }
}

Где общий хост теперь настроен так:

IHostBuilder builder = new HostBuilder()
    .UseServiceProviderFactory(new MyContainerFactory())
    .ConfigureServices((hostBuilderContext, services) => {
        services.AddHostedService<MyService>();
     });

С MyContainerFactory, настроенным так:

class MyContainerFactory : IServiceProviderFactory<SomeContainer> {
    public SomeContainer CreateBuilder(IServiceCollection services) {
        return SomeContainer.SetupStuff().Create();
    }
    public IServiceProvider CreateServiceProvider(SomeContainer container) {
        return new MyCustomProvider(container);
    }
}

Учитывая, что мой пользовательский DI-контейнер успешно вызывается, я подозреваю, что нет ничего плохого в том, как настроен мой контейнер. Очевидно, он не может найти IHost, потому что MyService наследуется от IHostedService, но почему он пытается получить IHost в первую очередь? Что-то должно быть не так, но я просто не могу понять, где!

Почему мой общий хост пытается создать IHost вместо IHostedService при вызове AddHostedService()

1 Ответ

1 голос
/ 23 апреля 2019

Проблема заключается в том, что HostBuilder добавляет все специфические сервисы Generic Host к встроенному IServiceCollection, который передается на IServiceProviderFactory, однако на вашем заводе эти сервисы игнорируются.

Это приводит к тому, что вновь сгенерированный SomeContainer пропустит необходимые базовые службы (например, IHost, IConfiguration, ILoggerFactory и т. Д.).

IHost, который "отсутствует" (или, скорее, недоступен в вашем пользовательском DI), является классом , который запускает все размещенные службы.

Решение состоит в том, чтобы добавить все службы (или, по крайней мере, IHost, но в дальнейшем могут вызвать некоторые другие пропущенные службы) к вашему SomeContainer в IServiceProviderFactory.CreateBuilder.

...