Intro
ASP.NET core 配置默认是项目根目录下的 appsettings.JSON 文件, 还有环境变量以及 command line arguments, 有一些链接字符串等信息可能放在数据库里更好一些, 也方便修改与维护, 有的配置可能多个应用共享一些配置, 这样维护在数据库里可能就只需要配置一次. 有人可能说那你为什么不直接搞个配置中心呢, 开始是想直接接入一个配置中心, 后来觉得项目不大可以不必引入配置中心, 直接自己造个轮子从数据库读取配置就可以了, 于是就想自己实现一套基于数据库的 ConfigurationProvider
探索 Configuration
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));
- }
- }
更多源码参考:
使用
修改 Program 文件 webHost 的构建, 参考:
- WebHost.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(configBuilder =>
- {
- var configuration = configBuilder.Build();
- configBuilder.AddEntityFramework(config => config.UseSqlServer(configuration.GetConnectionString("Configurations"));
- })
- .UseStartup<Startup>();
源码
你可以修改源码来进一步定制符合你需要的基于数据库的 ConfigurationProvider
来源: https://www.cnblogs.com/weihanli/p/migrate-your-configuration-to-database.html