我們?cè)谇懊鎸?duì)配置模型中默認(rèn)提供的各種IConfigurationSource實(shí)現(xiàn)類型進(jìn)行了深入詳盡的介紹,如果它們依然不能滿足項(xiàng)目中的需求,我們還可以通過自定義IConfigurationSource實(shí)現(xiàn)類型來支持我們希望的配置源。就配置數(shù)據(jù)的持久化方式來說,將配置存儲(chǔ)在數(shù)據(jù)庫(kù)中應(yīng)該是一種常見的方式。接下來我們會(huì)創(chuàng)建一個(gè)針對(duì)數(shù)據(jù)庫(kù)的IConfigurationSource實(shí)現(xiàn)類型,它采用Entity Framework Core來完成數(shù)據(jù)庫(kù)的存取操作。
我們將這個(gè)自定義ConfigurationSource命名為DbConfigurationSource。在正式介紹它的實(shí)現(xiàn)之前,我們先來看看它在項(xiàng)目中的應(yīng)用。我們將配置保存在SQL Server數(shù)據(jù)庫(kù)中的某個(gè)數(shù)據(jù)表中,并采用Entity Framework Core來讀取它。我們將連接字符串作為配置定義在一個(gè)名為“appSettings.json”的JSON文件中。
{
"connectionStrings": {
"DefaultDb": "Server = ... ; Database=...; Uid = ...; Pwd = ..."
}
}
在如下所示的演示程序中,我們首先創(chuàng)建了一個(gè)ConfigurationBuilder對(duì)象,并在它上面注冊(cè)了一個(gè)指向connectionString.json文件的JsonConfigurationSource對(duì)象。針對(duì)DbConfigurationSource對(duì)象的注冊(cè)體現(xiàn)在擴(kuò)展方法AddDatabase上,這個(gè)方法具有兩個(gè)參數(shù),分別代表連接字符串的名稱和初始的配置數(shù)據(jù)。前者正是connectionString.json設(shè)置的連接字符串名稱DefaultDb,后者是一個(gè)字典對(duì)象,它提供的原始配置正好可以構(gòu)成一個(gè)Profile對(duì)象。在利用ConfigurationBuilde對(duì)象創(chuàng)建出相應(yīng)的IConfiguration對(duì)象之后,我們讀取配置將其綁定為一個(gè)Profile對(duì)象。
public class Program
{
static void Main()
{
var initialSettings = new Dictionary<string, string>
{
["Gender"] = "Male",
["Age"] = "18",
["ContactInfo:EmailAddress"] = "foobar@outlook.com",
["ContactInfo:PhoneNo"] = "123456789"
};
var profile = new ConfigurationBuilder()
.AddJsonFile("appSettings.json")
.AddDatabase("DefaultDb", initialSettings)
.Build()
.Get<Profile>();
Debug.Assert(profile.Gender == Gender.Male);
Debug.Assert(profile.Age == 18);
Debug.Assert(profile.ContactInfo.EmailAddress == "foobar@outlook.com");
Debug.Assert(profile.ContactInfo.PhoneNo == "123456789");
}
}
如上面的代碼片斷所示,針對(duì)DbConfigurationSource的應(yīng)用僅僅體現(xiàn)在我們?yōu)镮ConfigurationBuilder對(duì)象定義的AddDatabase擴(kuò)展方法上,所以使用起來是非常方便的,那么這個(gè)擴(kuò)展方法背后有著怎樣的邏輯實(shí)現(xiàn)呢?DbConfigurationSource采用Entity Framework Core并以Code First的方式進(jìn)行數(shù)據(jù)操作,如下所示的ApplicationSetting是表示基本配置項(xiàng)的POCO類型,我們將配置項(xiàng)的Key以小寫的方式存儲(chǔ)。另一個(gè)ApplicationSettingsContext是對(duì)應(yīng)的DbContext類型。
[Table("ApplicationSettings")]
public class ApplicationSetting
{
private string key;
[Key]
public string Key
{
get { return key; }
set { key = value.ToLowerInvariant(); }
}
[Required]
[MaxLength(512)]
public string Value { get; set; }
public ApplicationSetting()
{ }
public ApplicationSetting(string key, string value)
{
Key = key;
Value = value;
}
}
public class ApplicationSettingsContext : DbContext
{
public ApplicationSettingsContext(DbContextOptions options) : base(options)
{ }
public DbSet<ApplicationSetting> Settings { get; set; }
}
如下所示的是DbConfigurationSource類型的定義,它的構(gòu)造函數(shù)具有兩個(gè)參數(shù),第一個(gè)參數(shù)類型為Action<DbContextOptionsBuilder>,我們用這個(gè)委托對(duì)象來對(duì)創(chuàng)建DbContext采用的DbContextOptions進(jìn)行設(shè)置,另一個(gè)可選的參數(shù)用來指定一些需要自動(dòng)初始化的配置項(xiàng)。DbConfigurationSource在重寫的Build方法中利用這兩個(gè)對(duì)象 創(chuàng)建一個(gè)DbConfigurationProvider對(duì)象。
public class DbConfigurationSource : IConfigurationSource
{
private Action<DbContextOptionsBuilder> _setup;
private IDictionary<string, string> _initialSettings;
public DbConfigurationSource(Action<DbContextOptionsBuilder> setup, IDictionary<string, string> initialSettings = null)
{
_setup = setup;
_initialSettings = initialSettings;
}
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new DbConfigurationProvider(_setup, _initialSettings);
}
}
DbConfigurationProvider派生于抽象類ConfigurationProvider。在重寫的Load方法中,它會(huì)根據(jù)提供的Action<DbContextOptionsBuilder>創(chuàng)建ApplicationSettingsContext對(duì)象,并利用它從數(shù)據(jù)庫(kù)中讀取配置數(shù)據(jù)并轉(zhuǎn)換成字典對(duì)象并賦值給代表配置字典的Data屬性 。如果數(shù)據(jù)表中沒有數(shù)據(jù),該方法還會(huì)利用這個(gè)DbContext對(duì)象將提供的初始化配置添加到數(shù)據(jù)庫(kù)中。
public class DbConfigurationProvider: ConfigurationProvider
{
private readonly IDictionary<string, string> _initialSettings;
private readonly Action<DbContextOptionsBuilder> _setup;
public DbConfigurationProvider(Action<DbContextOptionsBuilder> setup, IDictionary<string, string> initialSettings)
{
_setup = setup;
_initialSettings = initialSettings?? new Dictionary<string, string>() ;
}
public override void Load()
{
var builder = new DbContextOptionsBuilder<ApplicationSettingsContext>();
_setup(builder);
using (ApplicationSettingsContext dbContext = new ApplicationSettingsContext(builder.Options))
{
dbContext.Database.EnsureCreated();
Data = dbContext.Settings.Any()
? dbContext.Settings.ToDictionary(it => it.Key, it => it.Value, StringComparer.OrdinalIgnoreCase)
: Initialize(dbContext);
}
}
private IDictionary<string, string> Initialize( ApplicationSettingsContext dbContext)
{
foreach (var item in _initialSettings)
{
dbContext.Settings.Add(new ApplicationSetting(item.Key, item.Value));
}
return _initialSettings.ToDictionary(it => it.Key, it => it.Value, StringComparer.OrdinalIgnoreCase);
}
}
實(shí)例演示中用來注冊(cè)DbConfigurationSource對(duì)象的擴(kuò)展方法AddDatabase具有如下的定義。該方法首先調(diào)用IConfigurationBuilder對(duì)象的Build方法創(chuàng)建出一個(gè)IConfiguration對(duì)象,并調(diào)用該對(duì)象[A5] 的擴(kuò)展方法GetConnectionString根據(jù)指定的連接字符串名稱得到完整的連接字符串。接下來我們調(diào)用構(gòu)造函數(shù)創(chuàng)建一個(gè)DbConfigurationSource對(duì)象并注冊(cè)到ConfigurationBuilder對(duì)象上。創(chuàng)建DbConfigurationSource對(duì)象時(shí)指定的Action<DbContextOptionsBuilder>會(huì)完成針對(duì)連接字符串的設(shè)置。
public static class DbConfigurationExtensions
{
public static IConfigurationBuilder AddDatabase( this IConfigurationBuilder builder, string connectionStringName, IDictionary<string, string> initialSettings = null)
{
var connectionString = builder.Build() .GetConnectionString(connectionStringName);
var source = new DbConfigurationSource( optionsBuilder => optionsBuilder.UseSqlServer(connectionString), initialSettings);
builder.Add(source);
return builder;
}
}
創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國(guó)云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開啟,新人活動(dòng)云服務(wù)器買多久送多久。
當(dāng)前文章:[ASP.NETCore3框架揭秘]配置[9]:自定義配置源-創(chuàng)新互聯(lián)
鏈接URL:http://www.chinadenli.net/article36/dgiepg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、營(yíng)銷型網(wǎng)站建設(shè)、網(wǎng)站收錄、自適應(yīng)網(wǎng)站、網(wǎng)站維護(hù)、網(wǎng)站設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容