实现自己的.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.1 August Update We released .NET Core 2.1.400-SDK . See .NET Core 2.1.400-SDK release notes for complete details on th...
Setting up a managed container cluster with AKS an... After building a Raspberry Pi Kubernetes Cluster , I wanted to see how quickly I could get up to speed on Kubernetes in...
Explore CosmosDB with .NET Core and MongoDB Have you had to design general purpose “metadata” tables in your SQL database that basically store column names and valu...
Automating .NET Core deployments to different plat... Recently I’ve been writing C# applications using .NET Core 2 to work with devices which can host different operating sys...
.NET Core微服务之基于IdentityServer建立AuthorizationServer... 一、IdentityServer的预备知识 要学习IdentityServer,事先得了解一下基于Token的验证体系,这是一个庞大的主题,涉及到Token,OAuth&OpenID,JWT,协议规范等等等等,园子里已...