扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
我们在前面对配置模型中默认提供的各种IConfigurationSource实现类型进行了深入详尽的介绍,如果它们依然不能满足项目中的需求,我们还可以通过自定义IConfigurationSource实现类型来支持我们希望的配置源。就配置数据的持久化方式来说,将配置存储在数据库中应该是一种常见的方式。接下来我们会创建一个针对数据库的IConfigurationSource实现类型,它采用Entity Framework Core来完成数据库的存取操作。
创新互联服务项目包括岳阳县网站建设、岳阳县网站制作、岳阳县网页制作以及岳阳县网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,岳阳县网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到岳阳县省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
我们将这个自定义ConfigurationSource命名为DbConfigurationSource。在正式介绍它的实现之前,我们先来看看它在项目中的应用。我们将配置保存在SQL Server数据库中的某个数据表中,并采用Entity Framework Core来读取它。我们将连接字符串作为配置定义在一个名为“appSettings.json”的JSON文件中。
{
"connectionStrings": {
"DefaultDb": "Server = ... ; Database=...; Uid = ...; Pwd = ..."
}
}
在如下所示的演示程序中,我们首先创建了一个ConfigurationBuilder对象,并在它上面注册了一个指向connectionString.json文件的JsonConfigurationSource对象。针对DbConfigurationSource对象的注册体现在扩展方法AddDatabase上,这个方法具有两个参数,分别代表连接字符串的名称和初始的配置数据。前者正是connectionString.json设置的连接字符串名称DefaultDb,后者是一个字典对象,它提供的原始配置正好可以构成一个Profile对象。在利用ConfigurationBuilde对象创建出相应的IConfiguration对象之后,我们读取配置将其绑定为一个Profile对象。
public class Program
{
static void Main()
{
var initialSettings = new Dictionary
{
["Gender"] = "Male",
["Age"] = "18",
["ContactInfo:EmailAddress"] = "foobar@outlook.com",
["ContactInfo:PhoneNo"] = "123456789"
};
var profile = new ConfigurationBuilder()
.AddJsonFile("appSettings.json")
.AddDatabase("DefaultDb", initialSettings)
.Build()
.Get();
Debug.Assert(profile.Gender == Gender.Male);
Debug.Assert(profile.Age == 18);
Debug.Assert(profile.ContactInfo.EmailAddress == "foobar@outlook.com");
Debug.Assert(profile.ContactInfo.PhoneNo == "123456789");
}
}
如上面的代码片断所示,针对DbConfigurationSource的应用仅仅体现在我们为IConfigurationBuilder对象定义的AddDatabase扩展方法上,所以使用起来是非常方便的,那么这个扩展方法背后有着怎样的逻辑实现呢?DbConfigurationSource采用Entity Framework Core并以Code First的方式进行数据操作,如下所示的ApplicationSetting是表示基本配置项的POCO类型,我们将配置项的Key以小写的方式存储。另一个ApplicationSettingsContext是对应的DbContext类型。
[Table("ApplicationSettings")]
public class ApplicationSetting
{
private string key;
[Key]
public string Key
{
get { return key; }
set { key = value.ToLowerInvariant(); }
}
[Required]
[MaxLength(512)]
public string Value { get; set; }
public ApplicationSetting()
{ }
public ApplicationSetting(string key, string value)
{
Key = key;
Value = value;
}
}
public class ApplicationSettingsContext : DbContext
{
public ApplicationSettingsContext(DbContextOptions options) : base(options)
{ }
public DbSet Settings { get; set; }
}
如下所示的是DbConfigurationSource类型的定义,它的构造函数具有两个参数,第一个参数类型为Action
public class DbConfigurationSource : IConfigurationSource
{
private Action
private IDictionary
public DbConfigurationSource(Action setup, IDictionary initialSettings = null)
{
_setup = setup;
_initialSettings = initialSettings;
}
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new DbConfigurationProvider(_setup, _initialSettings);
}
}
DbConfigurationProvider派生于抽象类ConfigurationProvider。在重写的Load方法中,它会根据提供的Action
public class DbConfigurationProvider: ConfigurationProvider
{
private readonly IDictionary _initialSettings;
private readonly Action _setup;
public DbConfigurationProvider(Action setup, IDictionary initialSettings)
{
_setup = setup;
_initialSettings = initialSettings?? new Dictionary() ;
}
public override void Load()
{
var builder = new DbContextOptionsBuilder();
_setup(builder);
using (ApplicationSettingsContext dbContext = new ApplicationSettingsContext(builder.Options))
{
dbContext.Database.EnsureCreated();
Data = dbContext.Settings.Any()
? dbContext.Settings.ToDictionary(it => it.Key, it => it.Value, StringComparer.OrdinalIgnoreCase)
: Initialize(dbContext);
}
}
private IDictionary Initialize( ApplicationSettingsContext dbContext)
{
foreach (var item in _initialSettings)
{
dbContext.Settings.Add(new ApplicationSetting(item.Key, item.Value));
}
return _initialSettings.ToDictionary(it => it.Key, it => it.Value, StringComparer.OrdinalIgnoreCase);
}
}
实例演示中用来注册DbConfigurationSource对象的扩展方法AddDatabase具有如下的定义。该方法首先调用IConfigurationBuilder对象的Build方法创建出一个IConfiguration对象,并调用该对象[A5] 的扩展方法GetConnectionString根据指定的连接字符串名称得到完整的连接字符串。接下来我们调用构造函数创建一个DbConfigurationSource对象并注册到ConfigurationBuilder对象上。创建DbConfigurationSource对象时指定的Action
public static class DbConfigurationExtensions
{
public static IConfigurationBuilder AddDatabase( this IConfigurationBuilder builder, string connectionStringName, IDictionary initialSettings = null)
{
var connectionString = builder.Build() .GetConnectionString(connectionStringName);
var source = new DbConfigurationSource( optionsBuilder => optionsBuilder.UseSqlServer(connectionString), initialSettings);
builder.Add(source);
return builder;
}
}
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流