实现自己的.NET Core配置Provider之EF

综合编程 2017-06-29

《10分钟就能学会.NET Core配置》
里详细介绍了.NET Core配置的用法,另外我还开源了自定义的配置Provider:EF配置Provider和Yaml配置Provider。本文先来聊聊EF配置Provider的实现,其中会涉及到EntityFramework Core的知识,不熟悉也没关系,且听我慢慢讲来。

配置执行流程

在使用配置的时候都是先 new ConfigurationBuilder()
,最后调用 Build()
方法赋值给 Configuration
属性。那我们就从这个Build方法说起。

Build方法做了什么呢,它遍历了所有的配置源,等等,配置源哪来的?还记不记得 AddJsonFile
, AddCommandLine
这些扩展方法,它们做的事情就是将配置源添加到ConfigurationBuild中。每个配置源都有一个Build方法,它返回一个Provider。遍历所有配置源时调用配置源的Build方法,就获得了所有配置源的Provider,最后通过构造函数传给 ConfigurationRoot

每个Provider里都有一个 Load
方法,ConfigurationRoot的构造函数会遍历所有的Provider,调用它的Load方法。Load方法里需要做的就是把配置源里的配置转换为 IDictionary

了解了配置执行的流程,就可以动手实现自己的Provider了。

EF存储

Json配置Provider的配置存储在Json文件中,基于EF的Provider的配置则是存储在数据库中,因为使用了EF,我们不需要关心使用的是什么数据库。

在数据库中存储配置不支持嵌套和数组,只是简单的键值对形式,对应数据库表中的两列。使用EF,需要先定义一个实体存储配置,它包含两个属性,对应数据库表中的两列。

internal class Configuration
{
    public string Key { get; set; }

    public string Value { get; set; }
}

接着需要定义一个 ConfigurationDbContext
用于存储和访问配置。

internal class ConfigurationDbContext : DbContext
{
    private EFConfigurationOptionsBuilder Builder { get; }

    public ConfigurationDbContext(EFConfigurationOptionsBuilder options) : base(options.DbContextOptions.Options)
    {
        Builder = options;
    }

    public DbSet Configurations { get; set; }
}

EFConfigurationOptionsBuilder
是自定义的类,它包含2个属性,一个用于指定存储配置表的名称,另一个用于配置数据库连接及其他配置。

EFConfigurationProvider

自定义Provider可继承 ConfigurationProvider
实现。在ConfigurationProvider中Load是一个虚方法,自定义Provider需要实现Load方法。

internal class EFConfigurationProvider : ConfigurationProvider
{
    Action OptionsAction { get; }

    public EFConfigurationProvider(Action optionsAction)
    {
        OptionsAction = optionsAction;
    }

    public override void Load()
    {
        var builder = new EFConfigurationOptionsBuilder();
        OptionsAction(builder);
        using (var ctx = new ConfigurationDbContext(builder))
        {
            ctx.Database.EnsureCreated();
            Data = ctx.Configurations.ToDictionary(t => t.Key, t => t.Value);
        }
    }
}

EFConfigurationSource

EFConfigurationSource继承 IConfigurationSource
,实现了Build方法,在Build中返回EFConfigurationProvider。

internal class EFConfigurationSource : IConfigurationSource
{
    private readonly Action _optionsAction;

    public EFConfigurationSource(Action optionsAction)
    {
        _optionsAction = optionsAction;
    }

    public IConfigurationProvider Build(IConfigurationBuilder builder)
    {
        return new EFConfigurationProvider(_optionsAction);
    }
}

AddEntityFramework扩展方法

为添加EF配置源增加一个扩展方法。

public static class EFConfigurationExtensions
{
    public static IConfigurationBuilder AddEntityFramework(this IConfigurationBuilder builder, Action setup)
    {
        return builder.Add(new EFConfigurationSource(setup));
    }
}

使用EF配置Provider

var builder = new ConfigurationBuilder()
    .AddEntityFramework(options =>
    {
        options.TableName = "configs";
        // 这里使用SQLite作为演示
        options.DbContextOptions.UseSqlite("Filename=config.db");
    });


Configuration = builder.Build();

上面我使用SQLite演示,也可以使用SQL Server、MySql、PostgreSQL等。默认配置表的名称为Configuration。

最后

本项目已在github上开源,地址: https://github.com/chengxulvtu/Cxlt.Extensions.Configuration

在项目中使用可以执行下面的命令

Install-Package Cxlt.Extensions.Configuration.EF

dotnet add package Cxlt.Extensions.Configuration.EF

下篇文章《实现自己的.NET Core配置Provider之Yaml》将讲解Yaml配置Provider的细节。

如果这篇文章对你有帮助,请点赞支持一下,也欢迎关注“chengxulvtu"公众号。

博客园精华区

责编内容by:博客园精华区 (源链)。感谢您的支持!

您可能感兴趣的

.NET Core 2.0, Angular 4 and MySQL. Part 9 While sending HTTP requests towards our server, we need to use the HTTP Angular protocol. Of course,...
.NET Core 2.0, Angular 4, and MySQL Part 1 .NET Core 2.0, Angular 4, and MySQL Part 1 DZone's Guide to .NET Core 2.0, Angular 4, an...
React with .NET Core and MySQL – Form Validation a... As a continuation of the previous part, we are going to implement form validation and to create a...
携程Apollo(阿波罗)配置中心在.NET Core项目快速集成... .NET Core的支持文档大体上可以参考文档.Net客户端使用指南: https://github.com/ctripcorp/apollo/wiki/.Net%E5%AE%A2%E6%88%B7...
软件周刊 | 微软跨平台 .NET Core 2.0 终于发布... 微软跨平台 .NET Core 2.0 终于发布 微软发布了 .NET Core 2.0 版本,属于一次非常大的版本迭代。主要更新方面,包括对两个关键组成部分 Runtime(Cor...