ASP.NET Core 配置 - 創建自定義配置提供程序
在本文中,我們將創建一個自定義配置提供程序,從數據庫讀取我們的配置。我們已經瞭解了默認配置提供程序的工作方式,現在我們將實現我們自己的自定義配置提供程序。
對於自定義配置提供程序,我們將使用 Entity Framework Core,並結合 SQL Server 數據庫。
在這篇文章中,我們將討論:
•初始化 EF Core•實現自定義 EF Core 提供程序•運行應用程序•結論
首先,讓我們使用數據庫優先方法升級我們的解決方案以支持 EF Core 。
初始化 EF Core
在我們開始之前,我們需要先安裝兩個 Nuget 包: PM> Install-Package Microsoft.EntityFrameworkCore.SqlServer -v 3.1.7
我們需要這個包,因爲我們將使用 SQL Server 實例,並且: PM> Install-Package Microsoft.EntityFrameworkCore.Tools -v 3.1.7
因爲我們將通過 CLI 執行數據庫的初始創建和遷移。
我們需要一個包含鍵值配置對的類(Models 文件夾):
public class ConfigurationEntity
{
[Key]
public string Key { get; set; }
public string Value { get; set; }
}
和一個DbContext
類(模型文件夾):
public class ConfigurationDbContext : DbContext
{
public ConfigurationDbContext(DbContextOptions options)
: base(options)
{
}
public DbSet<ConfigurationEntity> ConfigurationEntities { get; set; }
}
我們只需要一個DbSet
的ConfigurationEntity
,這將映射到我們的數據庫中的表。
現在我們只需要ConfigureServices()
在Startup
類中的方法中建立到我們的服務器的連接:
services.AddDbContext<ConfigurationDbContext>(opts =>
opts.UseSqlServer(Configuration.GetConnectionString("sqlConnection")));
當然,您需要將appsettings.json
文件中的連接字符串更改爲您的數據庫。如果您使用的是 SqlExpress,它很可能如下所示:
"ConnectionStrings": {
"sqlConnection": "server=.\\SQLEXPRESS; database=CodeMazeCommerce; Integrated Security=true"
},
就是這樣,現在我們可以簡單地通過包管理器控制檯添加初始遷移: PM> Add-Migration InitialSetup
並將該遷移應用於數據庫: Update-Database
現在我們的數據庫已創建並準備好用於存儲配置數據。
實現自定義 EF Core 提供程序
首先,讓我們在 Models 文件夾中創建一個文件夾 ConfigurationProviders,以便正確地對我們的類進行分組。
之後,我們需要通過繼承ConfigurationProvider
類來實際創建一個配置提供者。我們將在ConfigurationProviders
文件夾中創建我們自己的提供程序類並將其命名爲EFConfigurationProvider
:
public class EFConfigurationProvider : ConfigurationProvider
{
public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
{
OptionsAction = optionsAction;
}
Action<DbContextOptionsBuilder> OptionsAction { get; }
public override void Load()
{
var builder = new DbContextOptionsBuilder<ConfigurationDbContext>();
OptionsAction(builder);
using (var dbContext = new ConfigurationDbContext(builder.Options))
{
dbContext.Database.EnsureCreated();
Data = !dbContext.ConfigurationEntities.Any()
? CreateAndSaveDefaultValues(dbContext)
: dbContext.ConfigurationEntities.ToDictionary(c => c.Key, c => c.Value);
}
}
private static IDictionary<string, string> CreateAndSaveDefaultValues(ConfigurationDbContext dbContext)
{
var configValues =
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "Pages:HomePage:WelcomeMessage", "Welcome to the ProjectConfigurationDemo Home Page" },
{ "Pages:HomePage:ShowWelcomeMessage", "true" },
{ "Pages:HomePage:Color", "black" },
{ "Pages:HomePage:UseRandomTitleColor", "true" }
};
dbContext.ConfigurationEntities.AddRange(configValues
.Select(kvp => new ConfigurationEntity
{
Key = kvp.Key,
Value = kvp.Value
})
.ToArray());
dbContext.SaveChanges();
return configValues;
}
}
這門課乍一看可能有點嚇人,但其實沒那麼嚇人。
構造函數有一個參數,即委託Action<DbContextOptionsBuilder> optionsAction
。稍後我們將使用DbContextOptionsBuilder
該類爲我們的數據庫定義上下文。我們之前定義連接字符串時已經完成了。我們公開了上下文選項構建器,以便向我們的自定義提供程序提供該選項。
我們正在重寫該Load()
方法,以便ConfigurationEntity
使用數據庫中的數據填充我們的方法,或者如果數據庫表爲空,則創建一些默認的方法。這裏的所有都是它的。
接下來,我們要將我們的配置提供程序註冊爲源。爲了做到這一點,我們需要實現IConfigurationSource
接口。所以讓我們EFConfigurationSource
在ConfigurationProviders
文件夾中創建類:
public class EFConfigurationSource : IConfigurationSource
{
private readonly Action<DbContextOptionsBuilder> _optionsAction;
public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction)
{
_optionsAction = optionsAction;
}
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new EFConfigurationProvider(_optionsAction);
}
}
我們只需要實現該Build()
方法,在我們的例子中,它會初始化配置,其中包含我們通過配置源構造函數發送的選項。
這看起來真的很令人困惑,所以讓我們看看如何將我們的數據庫配置提供程序添加到配置源列表中。我們將以與以前類似的方式進行:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureAppConfiguration((hostingContext, configBuilder) =>
{
var config = configBuilder.Build();
var configSource = new EFConfigurationSource(opts =>
opts.UseSqlServer(config.GetConnectionString("sqlConnection")));
configBuilder.Add(configSource);
});
如您所見,我們正在構建配置構建器以獲取IConfiguration
. 我們需要它,因爲我們的連接字符串存儲在appsettings.json
文件中。現在我們可以使用該連接字符串創建一個配置源,並使用該configBuilder.Add()
方法將其添加到現有配置源中。
現在我們要稍微清除一下 appsettings.json 文件:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"sqlConnection": "server=.\\SQLEXPRESS; database=CodeMazeCommerce; Integrated Security=true"
},
"AllowedHosts": "*"
}
我們刪除了“頁面”部分以確保它是從數據庫中讀取的。
我們需要刪除AddDbContext()
我們之前在 Startup 類中使用的方法,因爲它不再需要了。
public void ConfigureServices(IServiceCollection services)
{
//remove!!!
services.AddDbContext<ConfigurationDbContext>(opts =>
opts.UseSqlServer(Configuration.GetConnectionString("sqlConnection")));
...
}
由於本示例不需要任何遷移,因此請通過 SQL Management Studio 或通過 SQL Server 對象資源管理器手動創建一個名爲“CodeMazeCommerce”的數據庫。
就是這樣,讓我們運行應用程序。
運行應用程序
現在,如果我們運行應用程序,在Startup
類中放置一個斷點,並檢查Configuration
對象,我們將找到我們的配置源:
如果我們檢查數據庫,我們會看到它被填充:
讓我們繼續執行,看看我們的應用程序是否仍然按預期工作:
它仍然像以前一樣工作!您可以多次刷新頁面以確保標題的顏色仍會發生變化。
結論
在這篇簡短的文章中,我們已經瞭解瞭如何實現我們自己的自定義配置提供程序來讀取數據庫中的值。
本文分享自微信公衆號 - 一線碼農聊技術(dotnetfly)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。