依赖注入:根据环境调用不同的服务

Dependency Injection: call different services based on the environment

我正在构建一个 .net core 3.1 网络应用程序,并且正在试验内置依赖项注入。

我想根据应用程序所在的运行时环境注入不同的服务运行,我想我可以使用一个属性来定义服务是否适合该环境,例如:

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddTransient<IOperation, OperationDevelopment>();
    services.AddTransient<IOperation, OperationStaging>();
    services.AddTransient<IOperation, OperationProduction>();

    ...
}


public interface IOperation
{
    Guid OperationId { get; }
}

[Development]
public class OperationDevelopment : IOperation
{
}

[Staging]
public class OperationStaging : IOperation
{
}

[Production]
public class OperationProduction : IOperation
{
}

怎么办,跳过注册?全部注册然后解析合适的服务?我错过了什么?

如果.net core DI太基础,我该用什么?

谢谢

你能在方法中使用一个简单的 if 吗?希望对你有帮助

if (Environment.IsDevelopment())
{ 
    services.AddTransient<IOperation, OperationDevelopment>();
}
else
{
    services.AddTransient<IOperation, OperationProduction>();
}

假设在你的appsettings.json中,如果你配置了这样的环境变量

"environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }

然后在startup.cs中,抓取环境变量值

 public class Startup
    {
        public Startup(IConfiguration configuration, IWebHostEnvironment environment)
        {
            Configuration = configuration;
            Environment = environment;  
        }

        public IConfiguration Configuration { get; }
        public IWebHostEnvironment Environment { get; }

configureServices中捕获主机环境配置

public void ConfigureServices(IServiceCollection services)
        {

            string currentEnvironment= Environment.EnvironmentName;
            if(currentEnvironment== "Development")
            {
                services.AddTransient<IOperation, OperationDevelopment>();
            }
            else if (currentEnvironment == "Staging")
            {
                services.AddTransient<IOperation, OperationStaging>();
            }
            else if (currentEnvironment == "Production")
            {
                services.AddTransient<IOperation, OperationProduction>();
            }
        }

IWebHostEnvironment 适用于 .netcore 3.0(IHostEnvironment 适用于 .net core 2.2)

你可以这样做:

interface IOperationAttribute
{
}

[Development]
public class OperationDevelopment : IOperation
{
    public Guid OperationId { get; }
}

public class DevelopmentAttribute : Attribute, IOperationAttribute
{
}

为 IServiceCollection 添加新扩展

public static class AppServiceExtension
{    
    public static IServiceCollection AppOperationServices(this IServiceCollection services)
    {
        var typesWithOperationAttribute =
            from a in AppDomain.CurrentDomain.GetAssemblies()
            from t in a.GetTypes()
            let attributes = t.GetCustomAttributes(typeof(IOperationAttribute), true)
            where attributes != null && attributes.Length > 0
            select new { Type = t };

        foreach (var item in typesWithOperationAttribute)
            services.AddTransient((Type)item.Type);

        return services;
    }
}

然后在 ConfigureServices 中调用

services.AppOperationServices();