1. 程式人生 > >10分鐘就能學會的.NET Core配置

10分鐘就能學會的.NET Core配置

.NET Core為我們提供了一套用於配置的API,它為程式提供了執行時從檔案、命令列引數、環境變數等讀取配置的方法。配置都是鍵值對的形式,並且支援巢狀,.NET Core還內建了從配置反序列化為POCO物件的支援。

目前支援以下配置Provider:

  • 檔案(INI,JSON,XML)
  • 命令列引數
  • 環境變數
  • 記憶體中的.NET物件
  • User Secrets
  • Azure Key Vault

如果現有Provider不能滿足你的使用場景,還允許自定義Provider,比如從資料庫中讀取。

配置相關的包

包管理器中搜索“Microsoft.Extensions.Configuration",所有與配置相關的包都會列舉出來

配置相關的包

從包的名稱基本就可以看出它的用途,比如Microsoft.Extensions.Configuration.Json是Json配置的Provider,Microsoft.Extensions.Configuration.CommandLine是命令列引數配置的Provider,還有.NET Core程式中使用User Secrets儲存敏感資料這篇文章中使用的Microsoft.Extensions.Configuration.UserSecrets

檔案配置(以Json為例)

Json配置,需要安裝Microsoft.Extensions.Configuration.Json包。

命令列下安裝執行以下命令

dotnet add package Microsoft.Extensions.Configuration.Json -v 1.1.2

呼叫AddJsonFile把Json配置的Provider新增到ConfigurationBuilder中。

class Program
{
    public static IConfigurationRoot Configuration { get; set; }

    static void Main(string[] args)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json");

        Configuration = builder.Build();
    }
}

如果使用Xml或Ini,只需安裝相應的包,然後呼叫相應的擴充套件方法AddXmlFile("appsettings.xml)或AddIniFile("appsettings.ini")。

SetBasePath是指定從哪個目錄開始查詢appsettings.json。如果appsettings.json在configs目錄中,那麼呼叫AddJsonFile應該指定的路徑為"configs/appsettings.json"。

下面是演示用的Json配置,後面會講解所有讀取它的方法

{
  "AppId": "12345",
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "GrantTypes": [
    {
      "Name": "authorization_code"
    },
    {
      "Name": "password"
    },
    {
      "Name": "client_credentials"
    }
  ]
}

讀取JSON配置

1.使用Key讀取

Configuration["AppId"]; // 結果 12345
Configuration["Logging:IncludeScopes"]; // 結果 false
Configuration["Logging:LogLevel:Default"]; // 結果 Debug
Configuration["GrantTypes:0:Name"]; // 結果 authorization_code

讀取巢狀的配置,使用冒號隔開;讀取陣列形式的配置,使用陣列的下標索引,0表示第一個。

如在其他地方用到Configuration的時候,可以通過建構函式注入IConfiguration。

首先配置IConfiguration的依賴

services.AddSingleton<IConfiguration>(Configuration);

然後在通過建構函式注入

private readonly IConfiguration _configuration;
public GetConfig(IConfiguration configuration)
{
    _configuration = configuration;
}

2.使用GetValue<T>
這是一個擴充套件方法,使用它需要安裝Microsoft.Extensions.Configuration.Binder包。

Configuration.GetValue<int>("AppId", 12345); // 結果 12345
Configuration.GetValue<bool>("Logging:IncludeScopes", false); // 結果 false
Configuration.GetValue<string>("Logging:LogLevel:Default", "Debug"); // 結果 Debug
Configuration.GetValue<string>("GrantTypes:0:Name", "authorize_code"); // 結果 authorization_code

GetValue方法的泛型形式有兩個過載,一個是GetValue("key"),另一個可以指定預設值,GetValue("key",defaultValue)。如果key的配置不存在,第一種的結果為default(T),第二種的結果則為指定的預設值。

3.使用Options
這種方式需要安裝Microsoft.Extensions.Options.ConfigurationExtensions包。

呼叫AddOptions()新增使用Options需要的服務。

services.AddOptions()

定義與配置對應的POCO類

public class MyOptions
{
    public int AppId { get; set; }

    public LoggingOptions Logging { get; set; }

    public List<GrantType> GrantTypes { get; set; }

    public class GrantType
    {
        public string Name { get; set; }
    }
}

public class LoggingOptions
{
    public bool IncludeScopes { get; set; }

    public LogLevelOptions LogLevel { get; set; }
}

public class LogLevelOptions
{
    public string Default { get; set; }

    public string System { get; set; }

    public string Microsoft { get; set; }
}

繫結整個配置到POCO物件上

services.Configure<MyOptions>(Configuration);

也可以繫結特定節點的配置

services.Configure<LoggingOptions>(Configuration.GetSection("Logging"));

services.Configure<LogLevelOptions>(Configuration.GetSection("Logging:LogLevel"));

在需要用到配置的地方,通過建構函式注入,或者直接使用ServiceProvider獲取。

private readonly MyOptions _myOptions;
public GetConfig(IOptions<MyOptions> myOptionsAccessor)
{
    _myOptions = myOptionsAccessor.Value;
}

var myOptionsAccessor = serviceProvider.GetService<IOptions<MyOptions>>();
var myOptions = myOptionsAccessor.Value;

4.使用Get<T>
Get<T>是.NET Core 1.1才引入的。

var myOptions = Configuration.Get<MyOptions>();

var loggingOptions = Configuration.GetSection("Logging").Get<LoggingOptions>();

5.使用Bind
Get<T>類似,建議使用Get<T>

var myOptions = new MyOptions();
Configuration.Bind(myOptions);

var loggingOptions = new LoggingOptions();
Configuration.GetSection("Logging").Bind(loggingOptions);

檔案變化自動重新載入配置

IOptionsSnapshot支援配置檔案變化自動重新載入配置。使用IOptionsSnapshot也很簡單,AddJsonFile有個過載,指定reloadOnChange:true即可。

var builder = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("configs/appsettings.json", optional: false, reloadOnChange: true);

記憶體中配置

記憶體中配置呼叫AddInMemoryCollection(),其餘和Json配置一樣。

var dict = new Dictionary<string, string>
{
    {"AppId","12345"},
    {"Logging:IncludeScopes","false"},
    {"Logging:LogLevel:Default","Debug"},
    {"Logging:LogLevel:System","Information"},
    {"Logging:LogLevel:Microsoft","Information"},
    {"GrantTypes:0:Name","authorization_code"},
    {"GrantTypes:1:Name","password"},
    {"GrantTypes:2:Name","client_credentials"}
};

var builder = new ConfigurationBuilder()
    .AddInMemoryCollection(dict);

var builder = new ConfigurationBuilder()
    .AddInMemoryCollection();

Configuration["AppId"] = "12345";

命令列引數配置

命令列引數配置需要安裝Microsoft.Extensions.Configuration.CommandLine包。

呼叫AddCommandLine()擴充套件方法將命令列配置Provider新增到ConfigurationBuilder中。

var builder = new ConfigurationBuilder()
    .AddCommandLine(args);

傳遞引數有兩種形式

dotnet run /AppId=12345

dotnet run --AppId 12345

如果為--AppId提供一個縮寫的引數-a,那麼執行dotnet run -a 12345會報在switch mappings中沒有-a定義的錯誤。

幸好AddCommandLine還有一個過載,可以傳一個switch mapping。

var builder = new ConfigurationBuilder()
.AddCommandLine(args, new Dictionary<string, string>
{
    {"-a","AppId"}
});

這樣再執行下面的命令就不會報錯了。

dotnet run -a 12345

環境變數配置

環境變數配置需要安裝Microsoft.Extensions.Configuration.EnvironmentVariables包。

呼叫AddEnvironmentVariables()擴充套件方法將環境變數配置Provider新增到ConfigurationBuilder中。

var builder = new ConfigurationBuilder()
    .AddEnvironmentVariables();

獲取所有的環境變數

Environment.GetEnvironmentVariables();

根據名稱獲取環境變數

Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

自定義配置Provider

自定義配置Provider需要繼承IConfigurationSource實現自己的配置源,以及繼承ConfigurationProvider,重寫Load方法。

配置Provider順序

.NET Core的配置API允許同時使用多個配置Provider。

var builder = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("configs/appsettings.json")
    .AddXmlFile("configs/appsettings.xml")
    .AddCommandLine(args)
    .AddEnvironmentVariables();

如果兩個Provider都有相同的配置,那麼新增Provider的順序就非常重要了,因為後加入的會覆蓋前面的。

另外建議環境變數的配置Provider放到最後。

最後

.NET Core的配置是很基礎的內容,學起來自然不難,基本上動手實踐一遍就能掌握。越是簡單的東西,在日後的開發中可能幫你節約很多時間。

如果這篇文章對你有幫助或有什麼問題,歡迎關注“chengxulvtu"公眾號。