zoukankan      html  css  js  c++  java
  • 实现自己的.NET Core配置Provider之EF

    《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<string,string>

    了解了配置执行的流程,就可以动手实现自己的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<Configuration> Configurations { get; set; }
    }
    

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

    EFConfigurationProvider

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

    internal class EFConfigurationProvider : ConfigurationProvider
    {
        Action<EFConfigurationOptionsBuilder> OptionsAction { get; }
    
        public EFConfigurationProvider(Action<EFConfigurationOptionsBuilder> 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<EFConfigurationOptionsBuilder> _optionsAction;
    
        public EFConfigurationSource(Action<EFConfigurationOptionsBuilder> 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<EFConfigurationOptionsBuilder> 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"公众号。

  • 相关阅读:
    TZOJ 挑战题库随机训练03
    版本问题解决NoNodeAvailableException[None of the configured nodes are available
    [Caffe]使用经验积累
    [Torch]的安装
    [Caffe]史上最全的caffe安装过程
    [目标检测]PVAnet原理
    [目标检测]YOLO原理
    [目标检测]SSD原理
    [C++]返回最值元素
    [C++]智能指针的实现与使用
  • 原文地址:https://www.cnblogs.com/nianming/p/7092652.html
Copyright © 2011-2022 走看看