如何使用工厂模式和 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>();

并使用任意键解决它。