• ASP.NET Core的配置(4):多样性的配置来源[下篇]


    我们在上篇中篇对配置模型中默认提供的各种ConfigurationProvider进行了深入详尽的介绍,如果它们依然不能满足项目中的配置需求,我们可以还可以通过自定义ConfigurationProvider来支持我们希望的配置来源。就配置数据的持久化方式来说,将配置存储在数据库中应该是一种非常常见的方式,接下来我们就是创建一个针对数据库的ConfigurationProvider,它采用最新的Entity Framework 7来完成数据库的存取操作。

    目录
    MemoryConfigurationProvider
    EnvironmentVariablesConfigurationProvider
    CommandLineConfigurationProvider
    JsonConfigurationProvider
    XmlConfiguationProvider
    IniConfigurationProvider
    自定义ConfigurationProvider

    我们将这个自定义ConfigurationProvider命名为DbConfigurationProvider。在正式对它的实现展开介绍之前,我们先来看看它在项目中的应用。我们创建一个ASP.NET Core控制台程序来演示对这个DbConfigurationProvider应用,由于我们需要使用到Entity Framework 7,并且采用SQL Server数据库,所以我们需要在project.json文件中按照如下的方式添加对“EntityFramework.MicrosoftSqlServer”这个NuGet包的依赖。

       1: {
       2:   ...
       3:   "dependencies": {
       4:     "Microsoft.Extensions.Configuration": "1.0.0-rc1-final",
       5:     "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final"
       6:   },
       7: }

    我们按照如下的方式读取相关配置并将绑定为一个Profile对象。我们调用自定义的扩展方法AddDatabase创建一个DbConfigurationProvider对象并将其注册到创建的ConfigurationBuilder对象上。我们在调用扩展方法AddDatabase的时候指定了连接的目标数据库,同时设置了一些初始的配置项(如果确保配置项存在于目标数据库中,这个参数是不需要指定的),它们提供了组成一个完整的Profile对象的基础数据。

       1: string connectionString = "...";
       2: Profile profile = new ConfigurationBuilder().AddDatabase(optionsBuilder => optionsBuilder.UseSqlServer(connectionString),
       3:         new Dictionary<string, string>
       4:         {
       5:             ["Profile:Gender"]                    = "Male",
       6:             ["Profile:Age"]                       = "18",
       7:             ["Profile:ContactInfo:Email"]         = "foobar@outlook.com",
       8:             ["Profile:ContactInfo:PhoneNo"]       = "123456789"
       9:         })
      10:     .Build().Get<Profile>("Profile");

    如上面的代码片断所示,针对自定义的DbConfigurationProvider的应用仅仅体现在我们为ConfigurationBuilder定义的扩展方法AddDatabase上,所以使用起来是非常方便的,那么这个扩展方法背后有着怎样的逻辑实现呢?DbConfigurationProvider采用Entity Framework 7以Code First的方式进行数据操作,如下所示的ApplicationSetting是表示基本配置项的POCO类型,我们将配置项的Key以小写的方式存储。另一个ApplicationSettingsContext是对应的DbContext类型。

       1: [Table("ApplicationSettings")]
       2: public class ApplicationSetting
       3: {
       4:     private string key;
       5:  
       6:     [Key]
       7:     public string Key
       8:     {
       9:         get { return key; }
      10:         set { key = value.ToLowerInvariant(); }
      11:     }
      12:  
      13:     [Required]
      14:     [MaxLength(512)]
      15:     public string Value { get; set; }
      16:  
      17:     public ApplicationSetting()
      18:     {}
      19:  
      20:     public ApplicationSetting(string key, string value)
      21:     {
      22:         this.Key     = key;
      23:         this.Value     = value;
      24:     }
      25: }
      26:  
      27: public class ApplicationSettingsContext : DbContext
      28: {
      29:     public ApplicationSettingsContext(DbContextOptions options) : base(options)
      30:     {}
      31:  
      32:     public DbSet<ApplicationSetting> Settings { get; set; }
      33: }

    如下所示的是DbConfigurationProvider和扩展方法AddDatabase的定义。DbConfigurationProvider它的构造函数具有两个参数,一个参数类型为Action<DbContextOptionsBuilder>,用来对创建DbContext采用的DbContextOptions进行设置,另一个可选的参数用来指定一些需要自动初始化的配置项。在重写的Load方法中,我们利用创建的DbContexts从数据库中读取所有的配置项并作为自身的配置字典。

       1: public class DbConfigurationProvider: ConfigurationProvider
       2: {
       3:     public Func<DbContextOptions> DbContextOptionsAccessor { get; private set; }
       4:  
       5:     public DbConfigurationProvider(Action<DbContextOptionsBuilder> setup, IEnumerable<KeyValuePair<string, string>> settings = null)
       6:     {
       7:         DbContextOptionsBuilder<ApplicationSettingsContext> optionsBuilder = new DbContextOptionsBuilder<ApplicationSettingsContext>();
       8:         setup(optionsBuilder);
       9:         this.DbContextOptionsAccessor = () => optionsBuilder.Options;
      10:  
      11:         if (settings!=null && settings.Any())
      12:         {
      13:             using (ApplicationSettingsContext dbContext = new ApplicationSettingsContext(this.DbContextOptionsAccessor()))
      14:             {
      15:                 dbContext.Database.EnsureCreated();
      16:                 foreach (var item in settings)
      17:                 {
      18:                     ApplicationSetting setting = dbContext.Settings.FirstOrDefault(it => it.Key == item.Key.ToLowerInvariant());
      19:                     if (null == setting)
      20:                     {
      21:                         dbContext.Settings.Add(new ApplicationSetting(item.Key, item.Value));
      22:                     }
      23:                     else
      24:                     {
      25:                         setting.Value = item.Value;
      26:                     }
      27:                 }
      28:                 dbContext.SaveChanges();
      29:             }
      30:         }
      31:     }
      32:  
      33:     public override void Load()
      34:     {
      35:         using (ApplicationSettingsContext dbContext = new ApplicationSettingsContext(this.DbContextOptionsAccessor()))
      36:         {
      37:             var dictionary = dbContext.Settings.ToDictionary(it => it.Key, it => it.Value);
      38:             this.Data = new Dictionary<string, string>(dictionary, StringComparer.OrdinalIgnoreCase);
      39:         }
      40:     }
      41: }
      42:  
      43: public static class DbConfigurationProviderExtensions
      44: {
      45:     public static IConfigurationBuilder AddDatabase(this IConfigurationBuilder builder, Action<DbContextOptionsBuilder> setup,
      46:         IEnumerable<KeyValuePair<string, string>> settings = null)
      47:     {
      48:         builder.Add(new DbConfigurationProvider(setup, settings));
      49:         return builder;
      50:     }
      51: }

    ASP.NET Core的配置(1):读取配置信息
    ASP.NET Core的配置(2):配置模型详解
    ASP.NET Core的配置(3): 将配置绑定为对象[上篇]
    ASP.NET Core的配置(3): 将配置绑定为对象[下篇]
    ASP.NET Core的配置(4):多样性的配置源[上篇]
    ASP.NET Core的配置(4):多样性的配置源[中篇]
    ASP.NET Core的配置(4):多样性的配置源[下篇]
    ASP.NET Core的配置(5):配置的同步[上篇]
    ASP.NET Core的配置(5):配置的同步[下篇]

  • 相关阅读:
    R语言中的字符串处理函数
    flask模板应用-javaScript和CSS中jinja2 --
    flask模板应用-自定义错误页面 --
    flask模板应用-消息闪现(flash()) --
    flask模板应用-加载静态文件:添加Favicon,使用CSS框架,使用宏加载静态资源 --
    flask模板应用-空白控制 --
    flask模板结构组织(局部模板、宏、模板继承)--
    flask模板的基本用法(定界符、模板语法、渲染模板),模板辅助工具(上下文、全局对象、过滤器、测试器、模板环境对象) --
    CSRF(跨站请求伪造)攻击 --
    XSS攻击原理、示例和防范措施 --
  • 原文地址:https://www.cnblogs.com/artech/p/asp-net-core-config-4-3.html
Copyright © 2020-2023  润新知