使用 .env (環境變數) 配置系統,是我們常用的手段之一,他的格式非常的簡單,就 key = value,攤平的結構
讀取 .env 檔也不是甚麼太大的問題,所以我打算將他整合到 IConfiguration
有關 Configuration 的使用方式可以參考以下
如何使用組態 Microsoft.Extensions.Configuration | 余小章 @ 大內殿堂 - 點部落 (dotblogs.com.tw)
如何使用應用程式秘密組態 | 余小章 @ 大內殿堂 - 點部落 (dotblogs.com.tw)
如何使用 Options Pattern for Microsoft.Extensions.Options (dotblogs.com.tw)
.NET Core / .NET Fx 應用程式如何在開發環境使用環境變數 | 余小章 @ 大內殿堂 - 點部落 (dotblogs.com.tw)
開發環境
- Windows 10
- Rider
- .NET 6
實作
.env 的格式規則如下
- 左邊是 key,右邊是 value
- # 是註解
.env 格式如下圖
不要忘了,機密性資料不要上版控
處理檔案的時候,一行一行解析等號,然後用 Environment.SetEnvironmentVariable() 設定環境變數
public class EnvFileConfigurationProvider : ConfigurationProvider
{
private readonly string _envFile;
public EnvFileConfigurationProvider(string envFile)
{
this._envFile = envFile;
}
public override void Load()
{
var filePath = this._envFile;
if (!File.Exists(filePath))
{
return;
}
foreach (var line in File.ReadAllLines(filePath))
{
if (line.Substring(0, 1) == "#")
{
continue;
}
var parts = line.Split('=',
StringSplitOptions.RemoveEmptyEntries);
if (parts.Length != 2)
{
continue;
}
Environment.SetEnvironmentVariable(parts[0], parts[1]);
}
}
}
實作 IConfigurationSource,由這個物件決定要用哪一個 IConfigurationProvider
public class EnvFileConfigurationSource : IConfigurationSource
{
private readonly string _envFile;
public EnvFileConfigurationSource(string envFile)
{
this._envFile = envFile;
}
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new EnvFileConfigurationProvider(this._envFile);
}
}
在擴充方法裡面建立 EnvFileConfigurationSource 並且調用 AddEnvironmentVariables
public static class EnvFileConfigurationExtensions
{
public static IConfigurationBuilder AddEnvFile(this IConfigurationBuilder builder, string envFile)
{
var source = new EnvFileConfigurationSource(envFile);
builder.Add(source);
builder.AddEnvironmentVariables();
return builder;
}
}
調用方式如下,這裡我使用 ConfigurationBuilder
[TestMethod]
public void 讀取ENV檔案()
{
var configRoot = new ConfigurationBuilder()
.AddEnvFile("secret.env")
.Build()
;
Assert.AreEqual("foo-bar", configRoot.GetSection("SQL_SERVER_CS").Value);
Assert.AreEqual("localhost:6379", configRoot.GetSection("REDIS_ENDPOINT").Value);
}
[TestMethod]
public void 讀取ENV檔案後綁定()
{
var configRoot = new ConfigurationBuilder()
.AddEnvFile("secret.env")
.Build()
;
var appSetting = configRoot.Get<AppSetting>();
Assert.AreEqual("foo-bar", appSetting.SQL_SERVER_CS);
Assert.AreEqual("localhost:6379", appSetting.REDIS_ENDPOINT);
}
參考資源
Using .env in .NET - Dusted Codes
範例位置
套件
以下套件還提供其他資料格式的讀取,比如像是 yaml
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET