.net core 3:为不同环境配置DI容器

.net core 3:为不同环境配置DI容器,.net,asp.net-core,.net-core,dependency-injection,unity-container,.net,Asp.net Core,.net Core,Dependency Injection,Unity Container,我正在将旧的.NETV4.5.1项目移植到最新的.NETCore。 对于旧.net framework项目中的依赖项注入,使用Unity容器,其中所有服务注册都存储在web.config中 Global.asax: UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); section.Configure(con

我正在将旧的.NETV4.5.1项目移植到最新的.NETCore。 对于旧.net framework项目中的依赖项注入,使用Unity容器,其中所有服务注册都存储在web.config中

Global.asax:

    UnityConfigurationSection section
        = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
    section.Configure(container, "unityContainer");
web.config:

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<container name="primaryUnityContainer">
      <register type="ILogger" mapTo="Log4NetLogger"/>

问题是:在.net core 3中,在应用程序外部的配置文件中配置服务的最佳方式是什么,例如在appsettings.json中,以便为不同的环境注册不同的实现

内置容器是否可以扩展,或者最好使用具有此功能的第三方


对于特定环境,还有哪些方法可以实现服务?您可以使用以下配置设置类型:

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
#if SOME_BUILD_FLAG_A
    .AddJsonFile($"appsettings.flag_a.json", optional: true)
#else
    .AddJsonFile($"appsettings.no_flag_a.json", optional: true)
#endif
    .AddEnvironmentVariables();
    this.configuration = builder.Build();
}

您可以选择以下配置设置类型:

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
#if SOME_BUILD_FLAG_A
    .AddJsonFile($"appsettings.flag_a.json", optional: true)
#else
    .AddJsonFile($"appsettings.no_flag_a.json", optional: true)
#endif
    .AddEnvironmentVariables();
    this.configuration = builder.Build();
}

无法在应用程序外部的ASP.NET核心中配置服务
Microsoft.Extensions.DependencyInjection
完全基于代码,虽然您可以使用其他DI容器,但它们必须在
Microsoft.Extensions.DependencyInjection
facade的框架内使用和配置

也就是说,ASP.NET核心中的“环境”是基于配置的。您不会为多个不同的环境多次编译应用程序。相反,您可以通过环境变量(如
ASPNETCORE\u environment
)或运行时传递环境(如通过CLI参数)在启动时指定环境

在这两种情况下,您都可以根据环境值在代码中进行分支。实际上,有三种方法可以利用环境值按环境配置不同的服务

  • IWebHostEnvironment
    注入
    启动

    private readonly IWebHostEnvironment _env;
    
    public Startup(IWebHostEnvironment env)
    {
        _env = env;
    }
    
    然后,在
    ConfigureServices
    中:

    if (_env.IsDevelopment())
    {
        ...
    }
    
    if (_env.IsProduction())
    {
        ...
    }
    
    if (_env.IsEnvironment("Foo"))
    {
        ...
    }
    
  • ConfigureServices
    使用基于约定的命名。换句话说,您可以为
    启动
    类定义不同的
    配置{EnvironmentName}服务
    方法:

    public void ConfigureDevelopmentServices(IServiceCollection services)
    {
        ...
    }
    
    public void ConfigureProductionServices(IServiceCollection services)
    {
        ...
    }
    
    public void ConfigureFooServices(IServiceCollection services)
    {
        ...
    }
    
  • 启动
    类本身使用基于约定的命名。实际上,您可以定义多个
    Startup
    类,如
    StartupDevelopment
    startupboo
    ,等等。一个问题是,在
    Program.cs
    中设置主机时,您不能再使用通用的
    UseStartup
    方法。相反,您需要非泛型的
    UseStartup
    ,它采用程序集名称字符串(因为您不知道在编译时实际需要什么启动类):


  • 无法在应用程序外部的ASP.NET核心中配置服务
    Microsoft.Extensions.DependencyInjection
    完全基于代码,虽然您可以使用其他DI容器,但它们必须在
    Microsoft.Extensions.DependencyInjection
    facade的框架内使用和配置

    也就是说,ASP.NET核心中的“环境”是基于配置的。您不会为多个不同的环境多次编译应用程序。相反,您可以通过环境变量(如
    ASPNETCORE\u environment
    )或运行时传递环境(如通过CLI参数)在启动时指定环境

    在这两种情况下,您都可以根据环境值在代码中进行分支。实际上,有三种方法可以利用环境值按环境配置不同的服务

  • IWebHostEnvironment
    注入
    启动

    private readonly IWebHostEnvironment _env;
    
    public Startup(IWebHostEnvironment env)
    {
        _env = env;
    }
    
    然后,在
    ConfigureServices
    中:

    if (_env.IsDevelopment())
    {
        ...
    }
    
    if (_env.IsProduction())
    {
        ...
    }
    
    if (_env.IsEnvironment("Foo"))
    {
        ...
    }
    
  • ConfigureServices
    使用基于约定的命名。换句话说,您可以为
    启动
    类定义不同的
    配置{EnvironmentName}服务
    方法:

    public void ConfigureDevelopmentServices(IServiceCollection services)
    {
        ...
    }
    
    public void ConfigureProductionServices(IServiceCollection services)
    {
        ...
    }
    
    public void ConfigureFooServices(IServiceCollection services)
    {
        ...
    }
    
  • 启动
    类本身使用基于约定的命名。实际上,您可以定义多个
    Startup
    类,如
    StartupDevelopment
    startupboo
    ,等等。一个问题是,在
    Program.cs
    中设置主机时,您不能再使用通用的
    UseStartup
    方法。相反,您需要非泛型的
    UseStartup
    ,它采用程序集名称字符串(因为您不知道在编译时实际需要什么启动类):


  • 不要将编译器指令用于此类操作。这太可怕了,而且是错误的。不要对这样的事情使用编译器指令。这太可怕了,而且是错误的。