我在 .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
错过所需的基本服务(例如 IHost
、IConfiguration
、ILoggerFactory
等(运行。
"缺少"(或者更确切地说,在自定义 DI 中不可用(的IHost
是运行所有托管服务的类。
解决方案是将所有服务(或至少IHost
,但以后可能会导致其他一些服务丢失(添加到您的SomeContainer
中 IServiceProviderFactory.CreateBuilder
。