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 文件夹):

  1. public class ConfigurationEntity
  2. {
  3. [Key]
  4. public string Key { get; set; }
  5. public string Value { get; set; }
  6. }

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

  1. public class ConfigurationDbContext : DbContext
  2. {
  3. public ConfigurationDbContext(DbContextOptions options)
  4. : base(options)
  5. {
  6. }
  7. public DbSet<ConfigurationEntity> ConfigurationEntities { get; set; }
  8. }

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

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

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

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

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

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

PM> Add-Migration InitialSetup

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

Update-Database

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

实现自定义 EF Core 提供程序

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

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

  1. public class EFConfigurationProvider : ConfigurationProvider
  2. {
  3. public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
  4. {
  5. OptionsAction = optionsAction;
  6. }
  7. Action<DbContextOptionsBuilder> OptionsAction { get; }
  8. public override void Load()
  9. {
  10. var builder = new DbContextOptionsBuilder<ConfigurationDbContext>();
  11. OptionsAction(builder);
  12. using (var dbContext = new ConfigurationDbContext(builder.Options))
  13. {
  14. dbContext.Database.EnsureCreated();
  15. Data = !dbContext.ConfigurationEntities.Any()
  16. ? CreateAndSaveDefaultValues(dbContext)
  17. : dbContext.ConfigurationEntities.ToDictionary(c => c.Key, c => c.Value);
  18. }
  19. }
  20. private static IDictionary<string, string> CreateAndSaveDefaultValues(ConfigurationDbContext dbContext)
  21. {
  22. var configValues =
  23. new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
  24. {
  25. { "Pages:HomePage:WelcomeMessage", "Welcome to the ProjectConfigurationDemo Home Page" },
  26. { "Pages:HomePage:ShowWelcomeMessage", "true" },
  27. { "Pages:HomePage:Color", "black" },
  28. { "Pages:HomePage:UseRandomTitleColor", "true" }
  29. };
  30. dbContext.ConfigurationEntities.AddRange(configValues
  31. .Select(kvp => new ConfigurationEntity
  32. {
  33. Key = kvp.Key,
  34. Value = kvp.Value
  35. })
  36. .ToArray());
  37. dbContext.SaveChanges();
  38. return configValues;
  39. }
  40. }

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

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

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

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

  1. public class EFConfigurationSource : IConfigurationSource
  2. {
  3. private readonly Action<DbContextOptionsBuilder> _optionsAction;
  4. public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction)
  5. {
  6. _optionsAction = optionsAction;
  7. }
  8. public IConfigurationProvider Build(IConfigurationBuilder builder)
  9. {
  10. return new EFConfigurationProvider(_optionsAction);
  11. }
  12. }

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

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

  1. public static IHostBuilder CreateHostBuilder(string[] args) =>
  2. Host.CreateDefaultBuilder(args)
  3. .ConfigureWebHostDefaults(webBuilder =>
  4. {
  5. webBuilder.UseStartup<Startup>();
  6. })
  7. .ConfigureAppConfiguration((hostingContext, configBuilder) =>
  8. {
  9. var config = configBuilder.Build();
  10. var configSource = new EFConfigurationSource(opts =>
  11. opts.UseSqlServer(config.GetConnectionString("sqlConnection")));
  12. configBuilder.Add(configSource);
  13. });

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

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

  1. {
  2. "Logging": {
  3. "LogLevel": {
  4. "Default": "Information",
  5. "Microsoft": "Warning",
  6. "Microsoft.Hosting.Lifetime": "Information"
  7. }
  8. },
  9. "ConnectionStrings": {
  10. "sqlConnection": "server=.\\SQLEXPRESS; database=CodeMazeCommerce; Integrated Security=true"
  11. },
  12. "AllowedHosts": "*"
  13. }

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

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

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. //remove!!!
  4. services.AddDbContext<ConfigurationDbContext>(opts =>
  5. opts.UseSqlServer(Configuration.GetConnectionString("sqlConnection")));
  6. ...
  7. }

由于本示例不需要任何迁移,因此请通过 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. kafka 的基本概念及使用场景

    本文为博主原创,未经允许不得转载: 1. Kafka 的使用场景: 1.日志收集:一个公司可以用Kafka收集各种服务的log,通过kafka以统一接口服务的方式开放给各种 consumer,例如ha ...

  2. 【ThreadX-GUIX】Azure RTOS GUIX和Azure RTOS GUIX Studio概述

    Azure GUIX嵌入式GUI是Microsoft的高级工业级GUI解决方案,专门针对深度嵌入式,实时和IoT应用程序而设计.Microsoft还提供了名为Azure RTOS GUIX Studi ...

  3. pybind11

    fatal error: Python.h: no such file or directory 在使用pybind11时,如果不做调整可能就会出现这样的情况,Python.h一般出现在usr/inc ...

  4. [转帖]京东大佬细说:Nginx反向代理时保持长连接,看完直呼"学到了!"

    https://mp.weixin.qq.com/s?__biz=MzU1MzE2NzIzMg==&mid=2247488405&idx=1&sn=7081ff4e0ac1de ...

  5. [转帖]使用 TiFlash

    TiDB试用 来源:TiDB  浏览 490 扫码 分享 2021-04-20 20:57:48 使用 TiFlash 按表构建 TiFlash 副本 查看表同步进度 使用 TiDB 读取 TiFla ...

  6. [转帖]人大金仓和PG的关系

    作者:山抹微云链接:https://www.zhihu.com/question/582960448/answer/2997151260来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转 ...

  7. [转帖]高性能异步io机制:io_uring

    文章目录 1.性能测试 1.1.FIO 1.2.rust_echo_benc 2.io_uring 2.1.io_uring_setup 2.2.io_uring_enter 2.3.io_uring ...

  8. 麒麟信安V3.4 安装PG15的过程

    麒麟信安V3.4 安装PG15的过程 背景 发现基于OpenEuler的几个系统使用CentOS的rpm包 安装PG数据库时有问题. 会提示缺少依赖的so文件. 今天想着解决一下, 就百度了一下并且进 ...

  9. [译]深入了解现代web浏览器(四)

    本文是根据Mariko Kosaka在谷歌开发者网站上的系列文章https://developer.chrome.com/blog/inside-browser-part4/翻译而来,共有四篇,该篇是 ...

  10. 从零开始配置vim(21)——lsp简介与treesitter 配置

    截止到上一篇文章,我们配置了neovim的很多内容了.具备了一些编辑器的常用功能了,而且可以胜任日常的文档编辑工作了.但是想作为一个可靠的代码编辑器还缺少重要的一环,即代码语法部分的支持. 在过去的v ...