具有自定义 DI 的通用托管尝试获取错误的类型



我在 .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?一定是哪里出了问题,但我就是不明白在哪里!

为什么我的通用主机在调用AddHostedService()时尝试创建一个IHost而不是IHostedService

问题是 HostBuilder 将所有特定于通用主机的服务添加到传递给IServiceProviderFactory的内置IServiceCollection中,但是在您的工厂中,这些服务被忽略了。

这会导致新生成的SomeContainer错过所需的基本服务(例如 IHostIConfigurationILoggerFactory等(运行。

"缺少"(或者更确切地说,在自定义 DI 中不可用(的IHost是运行所有托管服务的类。

解决方案是将所有服务(或至少IHost ,但以后可能会导致其他一些服务丢失(添加到您的SomeContainerIServiceProviderFactory.CreateBuilder

最新更新