ASP.NET Core 配置 - 创建自定义配置提供程序

在本文中,我们将创建一个自定义配置提供程序,从数据库读取我们的配置。我们已经了解了默认配置提供程序的工作方式,现在我们将实现我们自己的自定义配置提供程序。

对于自定义配置提供程序,我们将使用 Entity Framework Core,并结合 SQL Server 数据库。

在这篇文章中,我们将讨论:

  • 初始化 EF Core
  • 实现自定义 EF Core 提供程序
  • 运行应用程序
  • 结论

首先,让我们使用数据库优先方法升级我们的解决方案以支持 EF Core 。

初始化 EF Core

在我们开始之前,我们需要先安装两个 Nuget 包:

PM> Install-Package Microsoft.EntityFrameworkCore.SqlServer -v 3.1.7

我们需要这个包,因为我们将使用 SQL Server 实例,并且:

PM> Install-Package Microsoft.EntityFrameworkCore.Tools -v 3.1.7

因为我们将通过 CLI 执行数据库的初始创建和迁移。

我们需要一个包含键值配置对的类(Models 文件夹):

public class ConfigurationEntity
{
[Key]
public string Key { get; set; }
public string Value { get; set; }
}

和一个DbContext类(模型文件夹):

public class ConfigurationDbContext : DbContext
{
public ConfigurationDbContext(DbContextOptions options)
: base(options)
{
} public DbSet<ConfigurationEntity> ConfigurationEntities { get; set; }
}

我们只需要一个DbSetConfigurationEntity,这将映射到我们的数据库中的表。

现在我们只需要ConfigureServices()Startup类中的方法中建立到我们的服务器的连接:

services.AddDbContext<ConfigurationDbContext>(opts =>
opts.UseSqlServer(Configuration.GetConnectionString("sqlConnection")));

当然,您需要将appsettings.json文件中的连接字符串更改为您的数据库。如果您使用的是 SqlExpress,它很可能如下所示:

"ConnectionStrings": {
"sqlConnection": "server=.\\SQLEXPRESS; database=CodeMazeCommerce; Integrated Security=true"
},

就是这样,现在我们可以简单地通过包管理器控制台添加初始迁移:

PM> Add-Migration InitialSetup

并将该迁移应用于数据库:

Update-Database

现在我们的数据库已创建并准备好用于存储配置数据。

实现自定义 EF Core 提供程序

首先,让我们在 Models 文件夹中创建一个文件夹 ConfigurationProviders,以便正确地对我们的类进行分组。

之后,我们需要通过继承ConfigurationProvider类来实际创建一个配置提供者。我们将在ConfigurationProviders文件夹中创建我们自己的提供程序类并将其命名为EFConfigurationProvider

public class EFConfigurationProvider : ConfigurationProvider
{
public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
{
OptionsAction = optionsAction;
} Action<DbContextOptionsBuilder> OptionsAction { get; } public override void Load()
{
var builder = new DbContextOptionsBuilder<ConfigurationDbContext>(); OptionsAction(builder); using (var dbContext = new ConfigurationDbContext(builder.Options))
{
dbContext.Database.EnsureCreated(); Data = !dbContext.ConfigurationEntities.Any()
? CreateAndSaveDefaultValues(dbContext)
: dbContext.ConfigurationEntities.ToDictionary(c => c.Key, c => c.Value);
}
} private static IDictionary<string, string> CreateAndSaveDefaultValues(ConfigurationDbContext dbContext)
{
var configValues =
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "Pages:HomePage:WelcomeMessage", "Welcome to the ProjectConfigurationDemo Home Page" },
{ "Pages:HomePage:ShowWelcomeMessage", "true" },
{ "Pages:HomePage:Color", "black" },
{ "Pages:HomePage:UseRandomTitleColor", "true" }
}; dbContext.ConfigurationEntities.AddRange(configValues
.Select(kvp => new ConfigurationEntity
{
Key = kvp.Key,
Value = kvp.Value
})
.ToArray()); dbContext.SaveChanges(); return configValues;
}
}

这门课乍一看可能有点吓人,但其实没那么吓人。

构造函数有一个参数,即委托Action<DbContextOptionsBuilder> optionsAction。稍后我们将使用DbContextOptionsBuilder该类为我们的数据库定义上下文。我们之前定义连接字符串时已经完成了。我们公开了上下文选项构建器,以便向我们的自定义提供程序提供该选项。

我们正在重写该Load()方法,以便ConfigurationEntity使用数据库中的数据填充我们的方法,或者如果数据库表为空,则创建一些默认的方法。这里的所有都是它的。

接下来,我们要将我们的配置提供程序注册为源。为了做到这一点,我们需要实现IConfigurationSource接口。所以让我们EFConfigurationSourceConfigurationProviders文件夹中创建类:

public class EFConfigurationSource : IConfigurationSource
{
private readonly Action<DbContextOptionsBuilder> _optionsAction; public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction)
{
_optionsAction = optionsAction;
} public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new EFConfigurationProvider(_optionsAction);
}
}

我们只需要实现该Build()方法,在我们的例子中,它会初始化配置,其中包含我们通过配置源构造函数发送的选项。

这看起来真的很令人困惑,所以让我们看看如何将我们的数据库配置提供程序添加到配置源列表中。我们将以与以前类似的方式进行:

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureAppConfiguration((hostingContext, configBuilder) =>
{
var config = configBuilder.Build();
var configSource = new EFConfigurationSource(opts =>
opts.UseSqlServer(config.GetConnectionString("sqlConnection")));
configBuilder.Add(configSource);
});

如您所见,我们正在构建配置构建器以获取IConfiguration. 我们需要它,因为我们的连接字符串存储在appsettings.json文件中。现在我们可以使用该连接字符串创建一个配置源,并使用该configBuilder.Add()方法将其添加到现有配置源中。

现在我们要稍微清除一下 appsettings.json 文件:

{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"sqlConnection": "server=.\\SQLEXPRESS; database=CodeMazeCommerce; Integrated Security=true"
},
"AllowedHosts": "*"
}

我们删除了“页面”部分以确保它是从数据库中读取的。

我们需要删除AddDbContext()我们之前在 Startup 类中使用的方法,因为它不再需要了。

public void ConfigureServices(IServiceCollection services)
{
//remove!!!
services.AddDbContext<ConfigurationDbContext>(opts =>
opts.UseSqlServer(Configuration.GetConnectionString("sqlConnection")));
...
}

由于本示例不需要任何迁移,因此请通过 SQL Management Studio 或通过 SQL Server 对象资源管理器手动创建一个名为“CodeMazeCommerce”的数据库。

就是这样,让我们运行应用程序。

运行应用程序

现在,如果我们运行应用程序,在Startup类中放置一个断点,并检查Configuration对象,我们将找到我们的配置源:

![ef configuration provider](/Users/zouding/文档/blog/文章/自定义配置/DTO 和 POCO(或 POJO)有什么区别.png)

如果我们检查数据库,我们会看到它被填充:

让我们继续执行,看看我们的应用程序是否仍然按预期工作:

它仍然像以前一样工作!您可以多次刷新页面以确保标题的颜色仍会发生变化。

结论

在这篇简短的文章中,我们已经了解了如何实现我们自己的自定义配置提供程序来读取数据库中的值。

ASP.NET Core 配置 - 创建自定义配置提供程序的更多相关文章

  1. 002.Create a web API with ASP.NET Core MVC and Visual Studio for Windows -- 【在windows上用vs与asp.net core mvc 创建一个 web api 程序】

    Create a web API with ASP.NET Core MVC and Visual Studio for Windows 在windows上用vs与asp.net core mvc 创 ...

  2. 在ASP.NET Core中创建自定义端点可视化图

    在上篇文章中,我为构建自定义端点可视化图奠定了基础,正如我在第一篇文章中展示的那样.该图显示了端点路由的不同部分:文字值,参数,动词约束和产生结果的端点: 在本文中,我将展示如何通过创建一个自定义的D ...

  3. 跟我学: 使用 fireasy 搭建 asp.net core 项目系列之三 —— 配置

    ==== 目录 ==== 跟我学: 使用 fireasy 搭建 asp.net core 项目系列之一 —— 开篇 跟我学: 使用 fireasy 搭建 asp.net core 项目系列之二 —— ...

  4. [ASP.NET Core 3框架揭秘] 配置[1]:读取配置数据[上篇]

    提到"配置"二字,我想绝大部分.NET开发人员脑海中会立即浮现出两个特殊文件的身影,那就是我们再熟悉不过的app.config和web.config,多年以来我们已经习惯了将结构化 ...

  5. [ASP.NET Core 3框架揭秘] 配置[2]:读取配置数据[下篇]

    [接上篇]提到“配置”二字,我想绝大部分.NET开发人员脑海中会立即浮现出两个特殊文件的身影,那就是我们再熟悉不过的app.config和web.config,多年以来我们已经习惯了将结构化的配置定义 ...

  6. [ASP.NET Core 3框架揭秘] 配置[5]:配置数据与数据源的实时同步

    在<配置模型总体设计>介绍配置模型核心对象的时候,我们刻意回避了与配置同步相关的API,现在我们利用一个独立文章来专门讨论这个话题.配置的同步涉及到两个方面:第一,对原始的配置源实施监控并 ...

  7. [ASP.NET Core 3框架揭秘] 配置[3]:配置模型总体设计

    在<读取配置数据>([上篇],[下篇])上面一节中,我们通过实例的方式演示了几种典型的配置读取方式,接下来我们从设计的维度来重写认识配置模型.配置的编程模型涉及到三个核心对象,分别通过三个 ...

  8. [ASP.NET Core 3框架揭秘] 配置[7]:多样化的配置源[中篇]

    物理文件是我们最常用到的原始配置载体,而最佳的配置文件格式主要有三种,它们分别是JSON.XML和INI,对应的配置源类型分别是JsonConfigurationSource.XmlConfigura ...

  9. [ASP.NET Core 3框架揭秘] 配置[6]:多样化的配置源[上篇]

    .NET Core采用的这个全新的配置模型的一个主要的特点就是对多种不同配置源的支持.我们可以将内存变量.命令行参数.环境变量和物理文件作为原始配置数据的来源.如果采用物理文件作为配置源,我们可以选择 ...

  10. [ASP.NET Core 3框架揭秘] 配置[4]:将配置绑定为对象

    虽然应用程序可以直接利用通过IConfigurationBuilder对象创建的IConfiguration对象来提取配置数据,但是我们更倾向于将其转换成一个POCO对象,以面向对象的方式来使用配置, ...

随机推荐

  1. shell脚本(8)-流程控制if

    一.单if语法 1.语法格式: if [ condition ] #condition值为 then commands fi 2.举例: [root@localhost test20210725]# ...

  2. Vue之将前端的筛选结果导出为csv文件

    有导入就有导出哈!这里继导入之后记录一下导出的实现过程. 1.按钮部分: <el-button class="filter-item" style="margin- ...

  3. AHB-SRAMC Design-02

    AHB-SRAMC Design SRAMC(另外一种代码风格)解析 SRAM集成,顶层模块尽量不要写交互逻辑 module ahb_slave_if( input hclk, input hrest ...

  4. crypto常用算法

    欧几里得算法(辗转相除法) def gcd(a, b): if b == 0: return a else: return gcd(b, a % b) 扩展欧几里得算法 def ext_euclid( ...

  5. [转帖]聊聊redis的slowlog与latency monitor

    https://www.jianshu.com/p/95a9ce63ddb2 序 本文主要研究一下redis的slowlog与latency monitor slowlog redis在2.2.12版 ...

  6. [转帖]Java程序在K8S容器部署CPU和Memory资源限制相关设置

    2019-04-297279 版权 本文涉及的产品 容器服务 Serverless 版 ACK Serverless,317元额度 多规格 推荐场景: 立即试用 容器镜像服务 ACR,镜像仓库100个 ...

  7. [转帖]MySQL快速备份表

    https://www.cnblogs.com/JaxYoun/p/14264593.html 1.复制表结构及数据到新表 CREATE TABLE 新表 SELECT * FROM 旧表 这种方法会 ...

  8. [转帖]Docker-Compose 自动创建的网桥与局域网冲突解决方案

    https://zhuanlan.zhihu.com/p/379305319 Docker-Compose 自动创建的网桥与局域网冲突解决方案 当我使用docker-compose的方式部署内网的ha ...

  9. [转帖]使用Rclone实现minio数据的迁移

    使用Rclone实现minio数据的迁移 一.准备 1.1 使用工具 rclone:开源的对象存储在线迁移工具,用于文件和目录的同步,支持阿里云的oss.minio .亚马逊S3 等. 1.2 注意事 ...

  10. Jmeter之二_JSR223取样器,断言等添加失败的解决办法

    Jmeter之二_JSR223取样器,断言等添加失败的解决办法 背景 最近在学习jmeter 但是发现在进行JSR223的相关取样器以及断言处理时出现了错误: java.lang.NoClassDef ...