.NET Core基礎篇之:配置文件讀取
配置文件是每個項目最基礎的部分,也是不可或缺的部分,比如:數據庫連接、中間件屬性等常見的配置。
今天這篇文章主要內容就是,在.Net Core項目中怎樣去讀取配置文件並使用。
提前準備
appsettings.json
文件
{
"User": {
"userName": "趙一",
"userAge": 18
}
}
對應實體模型
public class UserOption
{
public string userName { get; set; }
public int userAge { get; set; }
}
常規讀取
1、註冊
在 startup 類中註冊,主要用到的是 Configure 方法:
services.Configure<UserOption>(Configuration.GetSection("User"));
2、控制器中注入並讀取
public class HomeController : ControllerBase
{
private readonly UserOption user;
public HomeController(IOptions<UserOption> userOptions)
{
user = userOptions.Value;
}
[HttpGet]
public string Get()
{
return $"姓名:{user.userName},年齡:{user.userAge} ";
}
}
輸出結果:姓名:趙一,年齡:18
嵌套讀取
我們對 appsettings.json
文件做一點小小的改動,增加一個子節點 child
:
{
"User": {
"userName": "趙一",
"userAge": 18,
"child": {
"userName": "趙一的崽",
"userAge": 2
}
}
}
再對註冊的代碼做一點小小的修改:
services.Configure<UserOption>(Configuration.GetSection("User:child"));
輸出結果:姓名:趙一的崽,年齡:2
分實例讀取
這個時候需求又有變化了,需要同時讀取 User
與 child
節點的數據,我們試試下面的方法看可行不可行:
// 註冊
services.Configure<UserOption>(Configuration.GetSection("User"));
services.Configure<UserOption>(Configuration.GetSection("User:child"));
// 控制器
public class HomeController : ControllerBase
{
private readonly UserOption user;
private readonly UserOption child;
public HomeController(IOptions<UserOption> userOptions, IOptions<UserOption> childOptions)
{
user = userOptions.Value;
child = childOptions.Value;
}
[HttpGet]
public string Get()
{
return $"姓名:{user.userName},年齡:{user.userAge} \r\n姓名:{child.userName},年齡:{child.userAge}";
}
}
輸出結果很顯然滿足不了我們的需求:
姓名:趙一的崽,年齡:2
姓名:趙一的崽,年齡:2
有的小夥伴肯定會說,在實體模型內在加一個子節點字段。這樣肯定是沒問題的,但是與常規讀取方式就沒什麼兩樣了。
這裡我要說的是分實例讀取,引入 Configure
的另一個重載方法,與之前不同的是多了一個參數 name
:
public static IServiceCollection Configure<TOptions>(this IServiceCollection services, string name, IConfiguration config) where TOptions : class;
下面我們重新註冊:
services.Configure<UserOption>("father", Configuration.GetSection("User"));
services.Configure<UserOption>("son", Configuration.GetSection("User:child"));
在控制器構造函數中注入,也引入了一個新的接口對象:IOptionsMonitor
public class HomeController : ControllerBase
{
private readonly UserOption user;
private readonly UserOption child;
public HomeController(IOptionsMonitor<UserOption> userOptions, IOptionsMonitor<UserOption> childOptions)
{
user = userOptions.Get("father");
child = childOptions.Get("son");
}
[HttpGet]
public string Get()
{
return $"姓名:{user.userName},年齡:{user.userAge} \r\n姓名:{child.userName},年齡:{child.userAge}";
}
輸出結果:
姓名:趙一,年齡:18
姓名:趙一的崽,年齡:2
其實還有一個接口對象能實現這樣的效果:IOptionsSnapshot
,那 IOptionsMonitor
與 IOptionsSnapshot
有什麼不同呢?請接着往下看。
IOptionsMonitor與IOptionsSnapshot的不同之處
我們先來看看微軟官方的注釋:
IOptionsMonitor
//
// 摘要:
// Used for notifications when TOptions instances change.
//
// 類型參數:
// TOptions:
// The options type.
public interface IOptionsMonitor<out TOptions>
{
//
// 摘要:
// Returns the current TOptions instance with the Microsoft.Extensions.Options.Options.DefaultName.
TOptions CurrentValue { get; }
//
// 摘要:
// Returns a configured TOptions instance with the given name.
TOptions Get(string name);
//
// 摘要:
// Registers a listener to be called whenever a named TOptions changes.
//
// 參數:
// listener:
// The action to be invoked when TOptions has changed.
//
// 返回結果:
// An System.IDisposable which should be disposed to stop listening for changes.
IDisposable OnChange(Action<TOptions, string> listener);
}
IOptionsSnapshot
//
// 摘要:
// Used to access the value of TOptions for the lifetime of a request.
//
// 類型參數:
// TOptions:
// Options type.
public interface IOptionsSnapshot<out TOptions> : IOptions<TOptions> where TOptions : class, new()
{
//
// 摘要:
// Returns a configured TOptions instance with the given name.
TOptions Get(string name);
}
從字面上理解,IOptionsMonitor
建議在配置信息更改後需要通知的場景下使用,所以多了個 OnChange
的方法;而 IOptionsSnapshot
翻譯過來的意思是:用於在請求的生命周期內訪問配置,有點難以理解哈,我們接下來用代碼來驗證一下。
IOptionsMonitor 與 IOptionsSnapshot的生命周期
我們對實體模型再做一點小小的修改,增加一個 guid 字段,並給上默認值:
public class UserOption
{
public string userName { get; set; }
public int userAge { get; set; }
public Guid guid { get; set; } = Guid.NewGuid();
}
我們再次運行程序:
father — 姓名:趙一,年齡:19,編號:e0d71f47-e8f1-4a6d-875e-2074c985f4a0
son — 姓名:趙一的崽,年齡:3,編號:d865151b-f9bf-4eff-bb4e-8ab6dc61160c
然後不停的刷新頁面會發現,father
的編號沒有發生任何編號,而 son
的編號每次刷新都會改變。這是不是比較像我們註冊時所用到的三種模式:
services.AddScoped();
services.AddTransient();
services.AddSingleton()
其中 father
類似 AddSingleton
,son
則類似 AddScoped
與 AddTransient
。
大家可以在同一個方法里多次調用 childOptions.Get("son")
看看 son
到底時類似 AddScoped
還是 AddTransient
。
IOptionsMonitor的OnChange調用方式
userOptions.OnChange((user,name)=> { Console.WriteLine(user.userName +"-"+ name); });
無文件配置
無文件配置就是不需要以靜態文件的方式進行配置。相關信息在配置一次後就不用再做修改,我們可以採用無文件配置的方式,比如我們熟悉的 AddCors
跨域配置
services.AddCors(op => {
op.AddPolicy(CorsName, set => {
set.SetIsOriginAllowed(origin => true).AllowAnyHeader().AllowAnyMethod().AllowCredentials();
});
});
我們對之前的註冊方法進行一下改動:
services.Configure<UserOption>(c =>
{
c.userName = "錢二";
c.userAge = 60;
});
控制器注入採用常規的注入方式,最終輸出結果:姓名:錢二,年齡:60
以上就是本篇文章的全部內容了,因為時間有限,所以講到的內容比較少,以後時間充裕之後再做相關補充。
分享一個源碼查看網站://source.dot.net/