如何使用工厂模式和 Microsoft.Extensions.DependencyInjection 注册多个实现
How to register multiple implementations using factory pattern and Microsoft.Extensions.DependencyInjection
我有一个工厂方法设置 return 基于字符串值 IDeployApplicationService
的两个不同实现。
我在 Program.cs 中尝试了 .AddScoped()
或 .AddTransient()
的一些排列,但不确定为什么这个错误一直存在。
我的工厂
public class DeployApplicationServiceFactory : IDeployApplicationServiceFactory
{
private readonly IServiceProvider serviceProvider;
public DeployApplicationServiceFactory(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public IDeployApplicationService GetService(string environment)
{
if (environment.ToLower() == "prod")
{
// Error thrown in the line below.
// An exception of type 'System.InvalidOperationException' occurred
// in Microsoft.Extensions.DependencyInjection.Abstractions.dll
// but was not handled in user code: 'No service for type
// 'ProdDeployApplicationService' has been registered.'
return serviceProvider.GetRequiredService<ProdDeployApplicationService>();
}
else
{
return serviceProvider.GetRequiredService<NonProdDeployApplicationService>();
}
}
}
Program.cs(这是工人)
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.ConfigureServices((hostContext, services) =>
{
//[...]
services.AddScoped<IDeployApplicationServiceFactory, DeployApplicationServiceFactory>();
services.AddScoped<IDeployApplicationService, ProdDeployApplicationService>();
services.AddScoped<IDeployApplicationService, NonProdDeployApplicationService>();
//[...]
}
您已经通过其界面注册了服务:
services.AddScoped<IDeployApplicationService, ProdDeployApplicationService>()
这意味着您只能通过接口 serviceProvider.GetRequiredService<IDeployApplicationService>()
解析它,这将给您该接口注册的最后一个服务,NonProdDeployApplicationService
。
尝试自己注册(实现):
services.AddScoped<ProdDeployApplicationService>();
现在可以直接解析实现了:
serviceProvider.GetRequiredService<ProdDeployApplicationService>();
请记住,您可以多次注册 class:既可以单独注册,也可以通过它实现的 interfaces/abstract classes 注册:
// this is ok
services.AddScoped<ProdDeployApplicationService>();
services.AddScoped<IDeployService, ProdDeployApplicationService>();
services.AddScoped<IDeployApplicationService, ProdDeployApplicationService>();
并使用任意键解决它。
我有一个工厂方法设置 return 基于字符串值 IDeployApplicationService
的两个不同实现。
我在 Program.cs 中尝试了 .AddScoped()
或 .AddTransient()
的一些排列,但不确定为什么这个错误一直存在。
我的工厂
public class DeployApplicationServiceFactory : IDeployApplicationServiceFactory
{
private readonly IServiceProvider serviceProvider;
public DeployApplicationServiceFactory(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public IDeployApplicationService GetService(string environment)
{
if (environment.ToLower() == "prod")
{
// Error thrown in the line below.
// An exception of type 'System.InvalidOperationException' occurred
// in Microsoft.Extensions.DependencyInjection.Abstractions.dll
// but was not handled in user code: 'No service for type
// 'ProdDeployApplicationService' has been registered.'
return serviceProvider.GetRequiredService<ProdDeployApplicationService>();
}
else
{
return serviceProvider.GetRequiredService<NonProdDeployApplicationService>();
}
}
}
Program.cs(这是工人)
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.ConfigureServices((hostContext, services) =>
{
//[...]
services.AddScoped<IDeployApplicationServiceFactory, DeployApplicationServiceFactory>();
services.AddScoped<IDeployApplicationService, ProdDeployApplicationService>();
services.AddScoped<IDeployApplicationService, NonProdDeployApplicationService>();
//[...]
}
您已经通过其界面注册了服务:
services.AddScoped<IDeployApplicationService, ProdDeployApplicationService>()
这意味着您只能通过接口 serviceProvider.GetRequiredService<IDeployApplicationService>()
解析它,这将给您该接口注册的最后一个服务,NonProdDeployApplicationService
。
尝试自己注册(实现):
services.AddScoped<ProdDeployApplicationService>();
现在可以直接解析实现了:
serviceProvider.GetRequiredService<ProdDeployApplicationService>();
请记住,您可以多次注册 class:既可以单独注册,也可以通过它实现的 interfaces/abstract classes 注册:
// this is ok
services.AddScoped<ProdDeployApplicationService>();
services.AddScoped<IDeployService, ProdDeployApplicationService>();
services.AddScoped<IDeployApplicationService, ProdDeployApplicationService>();
并使用任意键解决它。