[ASP.NETCore3框架揭秘]配置[9]:自定義配置源-創(chuàng)新互聯(lián)

我們在前面對配置模型中默認(rèn)提供的各種IConfigurationSource實現(xiàn)類型進(jìn)行了深入詳盡的介紹,如果它們依然不能滿足項目中的需求,我們還可以通過自定義IConfigurationSource實現(xiàn)類型來支持我們希望的配置源。就配置數(shù)據(jù)的持久化方式來說,將配置存儲在數(shù)據(jù)庫中應(yīng)該是一種常見的方式。接下來我們會創(chuàng)建一個針對數(shù)據(jù)庫的IConfigurationSource實現(xiàn)類型,它采用Entity Framework Core來完成數(shù)據(jù)庫的存取操作。

網(wǎng)站建設(shè)公司,為您提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)頁設(shè)計及定制網(wǎng)站建設(shè)服務(wù),專注于成都企業(yè)網(wǎng)站定制,高端網(wǎng)頁制作,對成都垃圾桶等多個行業(yè)擁有豐富的網(wǎng)站建設(shè)經(jīng)驗的網(wǎng)站建設(shè)公司。專業(yè)網(wǎng)站設(shè)計,網(wǎng)站優(yōu)化推廣哪家好,專業(yè)成都網(wǎng)站推廣優(yōu)化,H5建站,響應(yīng)式網(wǎng)站。

我們將這個自定義ConfigurationSource命名為DbConfigurationSource。在正式介紹它的實現(xiàn)之前,我們先來看看它在項目中的應(yīng)用。我們將配置保存在SQL Server數(shù)據(jù)庫中的某個數(shù)據(jù)表中,并采用Entity Framework Core來讀取它。我們將連接字符串作為配置定義在一個名為“appSettings.json”的JSON文件中。

{
  "connectionStrings": {
    "DefaultDb":  "Server = ... ; Database=...; Uid = ...; Pwd = ..."
  }
}

在如下所示的演示程序中,我們首先創(chuàng)建了一個ConfigurationBuilder對象,并在它上面注冊了一個指向connectionString.json文件的JsonConfigurationSource對象。針對DbConfigurationSource對象的注冊體現(xiàn)在擴展方法AddDatabase上,這個方法具有兩個參數(shù),分別代表連接字符串的名稱和初始的配置數(shù)據(jù)。前者正是connectionString.json設(shè)置的連接字符串名稱DefaultDb,后者是一個字典對象,它提供的原始配置正好可以構(gòu)成一個Profile對象。在利用ConfigurationBuilde對象創(chuàng)建出相應(yīng)的IConfiguration對象之后,我們讀取配置將其綁定為一個Profile對象。

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");
}

}
如上面的代碼片斷所示,針對DbConfigurationSource的應(yīng)用僅僅體現(xiàn)在我們?yōu)镮ConfigurationBuilder對象定義的AddDatabase擴展方法上,所以使用起來是非常方便的,那么這個擴展方法背后有著怎樣的邏輯實現(xiàn)呢?DbConfigurationSource采用Entity Framework Core并以Code First的方式進(jìn)行數(shù)據(jù)操作,如下所示的ApplicationSetting是表示基本配置項的POCO類型,我們將配置項的Key以小寫的方式存儲。另一個ApplicationSettingsContext是對應(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ù)具有兩個參數(shù),第一個參數(shù)類型為Action<DbContextOptionsBuilder>,我們用這個委托對象來對創(chuàng)建DbContext采用的DbContextOptions進(jìn)行設(shè)置,另一個可選的參數(shù)用來指定一些需要自動初始化的配置項。DbConfigurationSource在重寫的Build方法中利用這兩個對象 創(chuàng)建一個DbConfigurationProvider對象。

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方法中,它會根據(jù)提供的Action<DbContextOptionsBuilder>創(chuàng)建ApplicationSettingsContext對象,并利用它從數(shù)據(jù)庫中讀取配置數(shù)據(jù)并轉(zhuǎn)換成字典對象并賦值給代表配置字典的Data屬性 。如果數(shù)據(jù)表中沒有數(shù)據(jù),該方法還會利用這個DbContext對象將提供的初始化配置添加到數(shù)據(jù)庫中。

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);
    }
}

實例演示中用來注冊DbConfigurationSource對象的擴展方法AddDatabase具有如下的定義。該方法首先調(diào)用IConfigurationBuilder對象的Build方法創(chuàng)建出一個IConfiguration對象,并調(diào)用該對象[A5] 的擴展方法GetConnectionString根據(jù)指定的連接字符串名稱得到完整的連接字符串。接下來我們調(diào)用構(gòu)造函數(shù)創(chuàng)建一個DbConfigurationSource對象并注冊到ConfigurationBuilder對象上。創(chuàng)建DbConfigurationSource對象時指定的Action<DbContextOptionsBuilder>會完成針對連接字符串的設(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è)提供香港、美國云服務(wù)器,動態(tài)BGP最優(yōu)骨干路由自動選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機房獨有T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動現(xiàn)已開啟,新人活動云服務(wù)器買多久送多久。

當(dāng)前文章:[ASP.NETCore3框架揭秘]配置[9]:自定義配置源-創(chuàng)新互聯(lián)
鏈接URL:http://www.muchs.cn/article36/dgiepg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、營銷型網(wǎng)站建設(shè)、網(wǎng)站收錄、自適應(yīng)網(wǎng)站、網(wǎng)站維護(hù)、網(wǎng)站設(shè)計

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)