《10分鐘就能學會.NET Core配置》裏詳細介紹了.NET Core配置的用法,另外我還開源了自定義的配置Provider:EF配置Provider和Yaml配置Provider。本文先來聊聊EF配置Provider的實現,其中會涉及到EntityFramework Core的知識,不熟悉也不要緊,且聽我慢慢講來。html
在使用配置的時候都是先new ConfigurationBuilder()
,最後調用Build()
方法賦值給Configuration
屬性。那咱們就從這個Build方法提及。git
Build方法作了什麼呢,它遍歷了全部的配置源,等等,配置源哪來的?還記不記得AddJsonFile
,AddCommandLine
這些擴展方法,它們作的事情就是將配置源添加到ConfigurationBuild中。每一個配置源都有一個Build方法,它返回一個Provider。遍歷全部配置源時調用配置源的Build方法,就得到了全部配置源的Provider,最後經過構造函數傳給ConfigurationRoot
。github
每一個Provider裏都有一個Load
方法,ConfigurationRoot的構造函數會遍歷全部的Provider,調用它的Load方法。Load方法裏須要作的就是把配置源裏的配置轉換爲IDictionary<string,string>
。數據庫
瞭解了配置執行的流程,就能夠動手實現本身的Provider了。數組
Json配置Provider的配置存儲在Json文件中,基於EF的Provider的配置則是存儲在數據庫中,由於使用了EF,咱們不須要關心使用的是什麼數據庫。bash
在數據庫中存儲配置不支持嵌套和數組,只是簡單的鍵值對形式,對應數據庫表中的兩列。使用EF,須要先定義一個實體存儲配置,它包含兩個屬性,對應數據庫表中的兩列。ide
internal class Configuration { public string Key { get; set; } public string Value { get; set; } }
接着須要定義一個ConfigurationDbContext
用於存儲和訪問配置。函數
internal class ConfigurationDbContext : DbContext { private EFConfigurationOptionsBuilder Builder { get; } public ConfigurationDbContext(EFConfigurationOptionsBuilder options) : base(options.DbContextOptions.Options) { Builder = options; } public DbSet<Configuration> Configurations { get; set; } }
EFConfigurationOptionsBuilder
是自定義的類,它包含2個屬性,一個用於指定存儲配置表的名稱,另外一個用於配置數據庫鏈接及其餘配置。ui
自定義Provider可繼承ConfigurationProvider
實現。在ConfigurationProvider中Load是一個虛方法,自定義Provider須要實現Load方法。this
internal class EFConfigurationProvider : ConfigurationProvider { Action<EFConfigurationOptionsBuilder> OptionsAction { get; } public EFConfigurationProvider(Action<EFConfigurationOptionsBuilder> optionsAction) { OptionsAction = optionsAction; } public override void Load() { var builder = new EFConfigurationOptionsBuilder(); OptionsAction(builder); using (var ctx = new ConfigurationDbContext(builder)) { ctx.Database.EnsureCreated(); Data = ctx.Configurations.ToDictionary(t => t.Key, t => t.Value); } } }
EFConfigurationSource繼承IConfigurationSource
,實現了Build方法,在Build中返回EFConfigurationProvider。
internal class EFConfigurationSource : IConfigurationSource { private readonly Action<EFConfigurationOptionsBuilder> _optionsAction; public EFConfigurationSource(Action<EFConfigurationOptionsBuilder> optionsAction) { _optionsAction = optionsAction; } public IConfigurationProvider Build(IConfigurationBuilder builder) { return new EFConfigurationProvider(_optionsAction); } }
爲添加EF配置源增長一個擴展方法。
public static class EFConfigurationExtensions { public static IConfigurationBuilder AddEntityFramework(this IConfigurationBuilder builder, Action<EFConfigurationOptionsBuilder> setup) { return builder.Add(new EFConfigurationSource(setup)); } }
var builder = new ConfigurationBuilder() .AddEntityFramework(options => { options.TableName = "configs"; // 這裏使用SQLite做爲演示 options.DbContextOptions.UseSqlite("Filename=config.db"); }); Configuration = builder.Build();
上面我使用SQLite演示,也可使用SQL Server、MySql、PostgreSQL等。默認配置表的名稱爲Configuration。
本項目已在github上開源,地址:https://github.com/chengxulvtu/Cxlt.Extensions.Configuration
在項目中使用能夠執行下面的命令
Install-Package Cxlt.Extensions.Configuration.EF
或
dotnet add package Cxlt.Extensions.Configuration.EF
下篇文章《實現本身的.NET Core配置Provider之Yaml》將講解Yaml配置Provider的細節。
若是這篇文章對你有幫助,請點贊支持一下,也歡迎關注「chengxulvtu"公衆號。