从 ASP.NET Core 控制器读取 docker-compose 环境变量

Mas*_*yan 4 asp.net environment-variables docker docker-compose asp.net-core

我正在尝试对 ASP.NET Core 5 Web API 项目进行 dockerize,因此我将把所有配置从appSettings.jsondocker-compose 环境部分转移。然后从控制器的环境部分读取它们。这个应该怎么做呢?

我尝试在控制器中使用IConfigurationand ,但我刚刚得到了.EnvironmentNull

我的Program.cs是:

namespace Order.Api
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
    }
}
Run Code Online (Sandbox Code Playgroud)

StartUp.cs

namespace Order.Api
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<OrderContext>(options =>
                options.UseSqlServer(Configuration.GetValue<string>("ConnectionString")));
                // options.UseSqlServer(Configuration.GetConnectionString("ConnectionString")));
            
            services.AddControllers();
            services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo {Title = "Order.Api", Version = "v1"}); });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Order.Api v1"));
            }

            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

docker-compose.override

version: '3.4'

services:

  Order.Api :
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://0.0.0.0:80
      - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sqldata;Database=Order;User Id=sa;Password=Pass@word}
      - MyConfig=Active
    ports:
      - "5001:80"


  sqldata :
    environment:
      - SA_PASSWORD=Pass@word
      - ACCEPT_EULA=Y
    ports:
      - "5433:1433"
    volumes:
      - order-sqldata:/var/opt/mssql



volumes:
  order-sqldata:
    external: false

Run Code Online (Sandbox Code Playgroud)

Exp*_*ten 12

ASP.NET Core提供从不同位置加载配置的能力:

  • appsettings.json
  • appsetting.<EnvName>.json
  • 环境变量
  • 用户秘密
  • 命令行参数

您不必担心设置的来源。从开发者的角度来看也是一样的。您可以将其想象为一堆层(每个下一层都会覆盖上一层的设置)。例如。当您的应用程序启动时,它会尝试从 中默认加载设置appsettings.json,然后通过 中的设置覆盖它appsetting.<EnvName>.json,然后从环境变量中等等。

因此,当您尝试覆盖ConnectionString环境变量时,首先需要检查它appsettings.json。那里是怎么定义的?让我们创建最简单的配置:

{
  "ConnectionStrings": {
    "ConnectionString": "from config"
  },
  "MyConfig": {
    "Key": "from config"
  }
}
Run Code Online (Sandbox Code Playgroud)

要读取 中的此连接Startup.cs,您无需更改任何内容。用你的options.UseSqlServer(Configuration.GetConnectionString("ConnectionString")));

要在环境变量中覆盖它,您需要为其提供特定名称:ConnectionStrings__ConnectionString=<new_connection>。这非常简单,您需要展平 JSON 配置并使用__(双下划线)作为分隔符。

对于自定义配置(如MyConfig),您需要做更多的事情。您需要创建选项类,例如:

public class MyConfigOption
{
    public string Key { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

并将其配置为Startup.cs

services.Configure<MyConfigOption>(Configuration.GetSection("MyConfig"));
Run Code Online (Sandbox Code Playgroud)

然后您将能够在环境变量中覆盖它MyConfig__Key=value

要在控制器中使用它,您需要向 DI 询问以下选项:

public Controller(IOptions<MyConfigOption> options)
{
    this.options = options;
}
Run Code Online (Sandbox Code Playgroud)

options将包含您的配置。

有关更多详细信息,请参阅文档。