是否可以向 IServiceProvider
添加服务?创建新范围时?
例如。一个范围是这样创建的:
using (var scope = Services.CreateScope())
{
// Register some service using "AddScoped"
scope.??.AddScoped<IOrganizationIdProvider, OrganizationIdProvider>((x) => { return new OrganizationIdProvider("dynamic-parameter")});
// Resolve service
scope.ServiceProvider.GetService<IOrganizationIdProvider>();
}
在范围内创建新实例时应解析该服务。
最佳答案
@Nkosi 已经提到,一旦容器被创建,你就不能在 MS.DI 中进行新的注册。但即使可以,在运行中更改容器也是一个坏主意,这就是为什么大多数 DI 容器不支持此类功能的原因。例如,最新版本的 Autofac 和 Ninject 最近删除了此类功能,以及 Simple Injector 文档 explains为什么它从来没有这个功能。
但是您可以通过对代码进行小的更改来实现您想要的。实现这一点的最简单方法可能是通过属性注入(inject)而不是构造函数注入(inject)来更改注入(inject)动态参数。例如:
应用程序代码更改:
public class OrganizationIdProvider : IOrganizationIdProvider
{
// Only required code change (notice that the interface doesn't change, this
// property is an implementation detail)
public string DynamicParameter { get; set; }
}
容器配置:
// Register the implementation by itself to allow it to be requested by your infrastructure
services.AddScoped<OrganizationIdProvider>();
// Register the provider by its interface so it can be injected into application components
services.AddScoped<IOrganizationIdProvider>(c => c.GetService<OrganizationIdProvider>());
用法:
using (var scope = Services.CreateScope())
{
// Here we resolve the OrganizationIdProvider *implementation*
var provider = scope.ServiceProvider.GetRequiredService<OrganizationIdProvider>();
// Set the runtime parameter
provider.DynamicParameter = "dynamic-parameter";
// Resolve service that might have a dependency on IOrganizationIdProvider.
var handler =
scope.ServiceProvider.GetRequiredService(typeof(IMessageHandler<DoSomething>));
// Use the service
handler.Handle(new DoSomething());
}
在处理运行时数据时肯定有更多选择,但为此我建议您阅读 this series on DI Composition Models .
关于c# - 创建新范围时添加范围服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61149889/