asp.net core 將配置文件配置遷移到資料庫(一) Intro asp.net core 配置預設是項目根目錄下的 appsettings.json 文件,還有環境變數以及 command line arguments,有一些鏈接字元串等信息可能放在資料庫里更好一些,也方便修改與維護,有的配 ...
asp.net core 將配置文件配置遷移到資料庫(一)
Intro
asp.net core 配置預設是項目根目錄下的 appsettings.json 文件,還有環境變數以及 command line arguments,有一些鏈接字元串等信息可能放在資料庫里更好一些,也方便修改與維護,有的配置可能多個應用共用一些配置,這樣維護在資料庫里可能就只需要配置一次。有人可能說那你為什麼不直接搞個配置中心呢,開始是想直接接入一個配置中心,後來覺得項目不大可以不必引入配置中心,直接自己造個輪子從資料庫讀取配置就可以了,於是就想自己實現一套基於資料庫的 ConfigurationProvider
探索 Configuration
Configuration 源碼在 https://github.com/aspnet/Extensions/tree/master/src/Configuration
微軟也提供了一些自己實現的 ConfigurationProvider
自定義基於 EF 的 ConfigurationProvider
需要實現兩個介面
- 實現
IConfigurationProvider
介面
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace WeihanLi.Configuration.EntityFramework
{
internal class EntityFrameworkConfigurationProvider : ConfigurationProvider
{
private readonly DbContextOptions<ConfigurationsDbContext> _dbContextOptions;
public EntityFrameworkConfigurationProvider(DbContextOptions<ConfigurationsDbContext> dbContextOptions)
{
_dbContextOptions = dbContextOptions;
}
public override void Load()
{
using (var dbContext = new ConfigurationsDbContext(_dbContextOptions))
{
var configurations = dbContext.Configurations.AsNoTracking()
.ToArray();
if (configurations.Length == 0)
return;
foreach (var configuration in configurations)
{
Data[configuration.Key] = configuration.Value;
}
}
}
}
}
- 實現
IConfigurationSource
介面
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace WeihanLi.Configuration.EntityFramework
{
internal class EntityFrameworkConfigurationSource : IConfigurationSource
{
private readonly Action<DbContextOptionsBuilder<ConfigurationsDbContext>> _action;
public EntityFrameworkConfigurationSource(Action<DbContextOptionsBuilder<ConfigurationsDbContext>> action)
{
_action = action;
}
private readonly DbContextOptionsBuilder<ConfigurationsDbContext> DbContextOptionsBuilder = new DbContextOptionsBuilder<ConfigurationsDbContext>();
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
_action.Invoke(DbContextOptionsBuilder);
return new EntityFrameworkConfigurationProvider(DbContextOptionsBuilder.Options);
}
}
}
擴展方法:
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace WeihanLi.Configuration.EntityFramework
{
public static class RedisConfigurationExtension
{
/// <summary>
/// Adds an <see cref="IConfigurationProvider"/> that reads configuration values from EntityFramework.
/// </summary>
/// <param name="builder">The <see cref="IConfigurationBuilder"/> to add to.</param>
/// <param name="action">Configures the configurationsDbContext source.</param>
/// <returns>The <see cref="IConfigurationBuilder"/>.</returns>
public static IConfigurationBuilder AddEntityFramework(this IConfigurationBuilder builder, Action<DbContextOptionsBuilder<ConfigurationsDbContext>> action)
=> builder.Add(new EntityFrameworkConfigurationSource(action));
}
}
更多源碼參考:https://github.com/WeihanLi/AspNetCorePlayground/tree/master/WeihanLi.Configuration.EntityFramework
使用
修改 Program 文件 WebHost 的構建,參考https://github.com/WeihanLi/AspNetCorePlayground/blob/master/TestWebApplication/Program.cs:
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(configBuilder =>
{
var configuration = configBuilder.Build();
configBuilder.AddEntityFramework(config => config.UseSqlServer(configuration.GetConnectionString("Configurations"));
})
.UseStartup<Startup>();
源碼
你可以修改源碼來進一步定製符合你需要的基於資料庫的 ConfigurationProvider