我有一些类库为我创建的应用程序提供服务,并且由于遗留原因,它们与DryIoc紧密绑定。也就是说,服务注册是紧密绑定的,而不是实际的服务。
如果可以的话,我宁愿不去修改那些代码,如果不需要的话。
创建一个新的ASP.NET MVC Core应用程序,我可以通过更改ConfigureServices方法以返回IServiceProvider来使用DryIoc:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddControllersAsServices();
var container = new Container().WithDependencyInjectionAdapter(services);
return container.ConfigureServiceProvider<CompositionRoot>();
}
(这是来自内存,因此可能不是100%正确,但这并不重要)
重要的变化是可以将void
方法更改为返回IServiceProvider
可以返回的DryIoc
。
但是,对于我想用于控制台应用程序,后台服务等的HostBuilder
,配置服务的方法不接受IServiceProvider
,所以我不确定该怎么做
重要的代码是这样:
var builder = new HostBuilder()
.ConfigureAppConfiguration((hostingContext, config) => { ... })
.ConfigureServices((hostContext, services) =>
{
services.AddOptions();
// configure services
})
.ConfigureLogging((hostingContext, logging) => { ... });
上面的ConfigureServices
方法有一个重载和一个扩展方法:
ConfigureServices(Action<HostBuilderContext, IServiceCollection> configureDelegate)
ConfigureServices(this IHostBuilder hostBuilder, Action<IServiceCollection> configureDelegate)
在这方面,似乎没有任何关于返回或使用IServiceProvider
或DryIoc
可以为我提供的任何其他规定。
这可能吗?有没有办法弥合差距?还是只需要对类库使用Microsoft IServiceCollection
?由于它们已在许多项目中使用,因此我不想因为在特定情况下看起来最简单而就进行更改,但如果需要的话,我必须这样做。
答案 0 :(得分:3)
@Nkosi提供了一个错误的答案(但在ASP.NET应用程序的上下文中是正确的),并且注释线程引发了关于方法UseServiceProviderFactory
的讨论。是解决方案,谢谢大家。
要使用UseServiceProviderFactory
,我必须自己实现一个类,并在项目中添加适当的nuget包引用。
以下是步骤:
DryIoc.dll
的引用(毫不奇怪)DryIoc.Microsoft.DependencyInjection
的引用UseServiceProviderFactory
所需的框架的自定义实现原始代码如下:
var builder = new HostBuilder()
.ConfigureAppConfiguration((hostingContext, config) => { ... })
.ConfigureServices((hostContext, services) =>
{
services.AddOptions();
// configure services
})
.ConfigureLogging((hostingContext, logging) => { ... });
以下是替代方法:
var builder = new HostBuilder()
.ConfigureAppConfiguration((hostingContext, config) => { ... })
.ConfigureServices((hostContext, services) =>
{
services.AddOptions();
// configure services
})
//////////////////// ADD THIS vvvvvvvv
.UseServiceProviderFactory(new DryIocServiceProviderFactory())
.ConfigureContainer<Container>((hostContext, container) =>
{
container.Register<...>();
})
//////////////////// ADD THIS ^^^^^^^^
.ConfigureLogging((hostingContext, logging) => { ... });
然后提供DryIocServiceProviderFactory
的此实现:
internal class DryIocServiceProviderFactory : IServiceProviderFactory<IContainer>
{
public IContainer CreateBuilder(IServiceCollection services)
=> new Container().WithDependencyInjectionAdapter(services);
public IServiceProvider CreateServiceProvider(IContainer containerBuilder)
=> containerBuilder.ConfigureServiceProvider<CompositionRoot>();
}
上面的CompositionRoot
类在配置过程中已解决,并且可以使用构造函数来配置容器。可以使用不执行任何操作的虚拟类。