C# 带有自定义DI的泛型主机试图获取错误的类型

C# 带有自定义DI的泛型主机试图获取错误的类型,c#,dependency-injection,.net-core,C#,Dependency Injection,.net Core,我使用的是.NET内核,我创建了一个IHostedService,它在我的通用主机中实例化如下: IHostBuilder builder = new HostBuilder() .ConfigureServices((hostBuilderContext, services) => { services.AddHostedService<MyService>(); }); IHostBuilder builder = new HostBui

我使用的是.NET内核,我创建了一个
IHostedService
,它在我的通用主机中实例化如下:

IHostBuilder builder = new HostBuilder()
    .ConfigureServices((hostBuilderContext, services) => {
        services.AddHostedService<MyService>();
     });
IHostBuilder builder = new HostBuilder()
    .UseServiceProviderFactory(new MyContainerFactory())
    .ConfigureServices((hostBuilderContext, services) => {
        services.AddHostedService<MyService>();
     });
class MyContainerFactory : IServiceProviderFactory<SomeContainer> {
    public SomeContainer CreateBuilder(IServiceCollection services) {
        return SomeContainer.SetupStuff().Create();
    }
    public IServiceProvider CreateServiceProvider(SomeContainer container) {
        return new MyCustomProvider(container);
    }
}
这个很好用

但是,如果我尝试使用自定义DI而不是Microsoft.Extensions.DependencyInjectionAddHostedService()请求一个
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()
    .ConfigureServices((hostBuilderContext, services) => {
        services.AddHostedService<MyService>();
     });
IHostBuilder builder = new HostBuilder()
    .UseServiceProviderFactory(new MyContainerFactory())
    .ConfigureServices((hostBuilderContext, services) => {
        services.AddHostedService<MyService>();
     });
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
。问题是主机生成器将所有通用主机特定的服务添加到传递给
IServiceProviderFactory
的内置
IServiceCollection
中,但是,在您的工厂中,这些服务被忽略

这会导致新生成的
SomeContainer
错过所需的基本服务(例如
IHost
IConfiguration
iLogger工厂
等)运行

“缺少”(或者在自定义DI中不可用)的
IHost
是运行所有托管服务的主机


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

您在这里使用的是什么“自定义DI”?您真的是自己构建一个容器,还是使用现有的容器?这一点很重要,因为大多数DI容器已经有了可用于.NET Core的集成,但其中很大一部分没有使用
UseServiceProviderFactory
和其他构造进行集成。这个模式被调用,您可以找到关于为什么某些容器不支持此模式的详细讨论。我使用的是
System.Composition
Ahh。。您正在使用MEF。我不确定MEF的组合模型是否与IServiceCollection隐式定义的注册API兼容,而且定义完全兼容的MEF适配器可能并不容易。相反,您可以尝试Castle Windsor、Ninject和Simple Injector采用的方法,即使用MEF作为应用程序容器,并将内置容器保留在适当的位置以创建框架组件。