C# 带有自定义DI的泛型主机试图获取错误的类型
我使用的是.NET内核,我创建了一个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
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作为应用程序容器,并将内置容器保留在适当的位置以创建框架组件。