zoukankan      html  css  js  c++  java
  • 多样性的配置来源[下篇]

    多样性的配置来源[下篇]

    我们在上篇中篇对配置模型中默认提供的各种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):配置的同步[下篇]

    作者:蒋金楠 
    微信公众账号:大内老A
    微博:www.weibo.com/artech
  • 相关阅读:
    Codechef EDGEST 树套树 树状数组 线段树 LCA 卡常
    BZOJ4319 cerc2008 Suffix reconstruction 字符串 SA
    Codechef STMINCUT S-T Mincut (CodeChef May Challenge 2018) kruskal
    Codeforces 316G3 Good Substrings 字符串 SAM
    Codechef CHSIGN Change the Signs(May Challenge 2018) 动态规划
    BZOJ1396 识别子串 字符串 SAM 线段树
    CodeForces 516C Drazil and Park 线段树
    CodeForces 516B Drazil and Tiles 其他
    CodeForces 516A Drazil and Factorial 动态规划
    SPOJ LCS2
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/5454464.html
Copyright © 2011-2022 走看看