• 设计系列系统配置


    一、前言

      在系统开发中,我们会使用很多配置信息,比如在web.Config文件配置数据库连接字符串、日志打印记录配置文件、接口信息配置文件、其他配置文件。配置文件让开发者对一些常量、不变的信息进行配置,在配置信息变动的时候只需要改变配置文件而不需要编辑代码。配置信息不仅可以配置在文件中,还可以在数据库中比如管理系统中的数据字典一样。所以每个系统基本上都要配置文件,如何统一管理配置文件,优雅简洁的获取配置文件,并且考虑分布式系统中共享配置文件的问题让我考虑设计一个通用的模块。以下是个人想法,代码处于比较简单的阶段。

    二、设计

      定义一个获取配置文件的服务接口IConfigService,接口内部定义两个方法,一个是获取配置文件、一个是保存配置文件(特殊需求编辑配置文件),由使用文件的方式获取配置文件FileConfigService和数据库获取配置文件SqlServerConfig类继承接口,实现接口方法。在ConfigModel文件夹中定义配置文件的数据模型,每一个模型对应一个配置信息,在文件的方式中使用配置文件对应,在数据库的方式中使用表的数据对应。通过配置文件上下文类ConfigContext来对外提供统一配置文件服务,该类隔离不同类型的配置方式获取配置信息具体细节,对外提供是一种无差别的配置服务。

      

     三、代码

    1、配置文件接口类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace TQF.Config.Demo.Config.ConfigService
    {
        /// <summary>
        /// 定义配置文件服务接口
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public interface IConfigService<T>
        {
            /// <summary>
            /// 获取配置文件数据
            /// </summary>
            /// <param name="configName">配置名称</param>
            /// <returns></returns>
            T GetConfig(string configName);
    
            /// <summary>
            /// 保存配置文件数据
            /// </summary>
            /// <param name="configName">配置名称</param>
            /// <param name="content">配置数据</param>
            void SaveConfig(string configName, T content);
        }
    }

    2、配置文件实现类

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Xml.Serialization;
    using TQF.Config.Demo.Helper;
    
    namespace TQF.Config.Demo.Config.ConfigService
    {
        /// <summary>
        /// 文件配置服务
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public class FileConfigService<T> : IConfigService<T>
        {
            protected readonly string FileFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ConfigFile");
    
            /// <summary>
            /// 获取系统配置信息
            /// </summary>
            /// <param name="configName"></param>
            /// <returns></returns>
            public T GetConfig(string configName)
            {
                try
                {
                    if (!Directory.Exists(FileFolder))
                    {
                        Directory.CreateDirectory(FileFolder);
                        return default(T);
                    }
    
                    var configFilePath = $@"{FileFolder}\{configName}.xml";
                    if (!File.Exists(configFilePath))
                    {
                        return default(T);
                    }
                    else
                    {
                        var content = File.ReadAllText(configFilePath);
                        if (!string.IsNullOrEmpty(content))
                        {
                            return (T)SerializationHelper.XmlDeserialize(typeof(T), content);
                        }
                        else
                        {
                            return default(T);
                        }
                    }
                }
                catch (Exception e)
                {
                    throw (e);
                }
            }
    
            /// <summary>
            /// 保存系统配置信息
            /// </summary>
            /// <param name="configName"></param>
            /// <param name="content"></param>
            public void SaveConfig(string configName, T content)
            {
                var configFilePath = $@"{FileFolder}\{configName}\.xml";
                if (File.Exists(configFilePath))
                {
                    File.WriteAllText(configFilePath, SerializationHelper.XmlSerialize(content));
                }
            }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace TQF.Config.Demo.Config.ConfigService
    {
        /// <summary>
        /// 数据库配置文件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public class SqlServerConfigService<T> : IConfigService<T>
        {
            /// <summary>
            /// 获取配置文件
            /// </summary>
            /// <param name="configName"></param>
            /// <returns></returns>
            public T GetConfig(string configName)
            {
                return default(T);
            }
    
            /// <summary>
            /// 保存配置文件
            /// </summary>
            /// <param name="configName"></param>
            /// <param name="content"></param>
            public void SaveConfig(string configName, T content)
            {
    
            }
        }
    }

    3、配置文件上下文类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using TQF.Config.Demo.Config.ConfigService;
    
    namespace TQF.Config.Demo.Config
    {
        /// <summary>
        /// 配置文件上下文类
        /// </summary>
        /// <typeparam name="TConfigSource">配置模型</typeparam>
        /// <typeparam name="TConfigService">配置服务</typeparam>
        public class ConfigContext<TConfigSource, TConfigService> where TConfigService : IConfigService<TConfigSource>, new()
        {
            /// <summary>
            /// 获取数据
            /// </summary>
            public static ConfigContext<TConfigSource, TConfigService> Current = new ConfigContext<TConfigSource, TConfigService>();
    
            /// <summary>
            /// 配置服务类型
            /// </summary>
            private IConfigService<TConfigSource> ConfigService { get; set; }
    
            /// <summary>
            /// 注入配置服务
            /// </summary>
            public ConfigContext()
            {
                ConfigService = new TConfigService();
            }
    
            /// <summary>
            /// 获取配置文件
            /// </summary>
            /// <param name="configName"></param>
            /// <returns></returns>
            public TConfigSource Get(string configName)
            {
                return ConfigService.GetConfig(configName);
            }
    
            /// <summary>
            /// 保存配置文件
            /// </summary>
            /// <param name="configName"></param>
            /// <param name="content"></param>
            public void Save(string configName, TConfigSource content)
            {
                ConfigService.SaveConfig(configName, content);
            }
        }
    }

    4、配置文件获取示例

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using TQF.Config.Demo.Config;
    using TQF.Config.Demo.Config.ConfigModel;
    using TQF.Config.Demo.Config.ConfigService;
    namespace TQF.Config.Demo
    {
        /// <summary>
        /// 系统配置文件管理
        /// </summary>
        class Program
        {
            static void Main(string[] args)
            {
                // 文件配置
                var fConfigData =  ConfigContext<CdpConfig, FileConfigService<CdpConfig>>.Current.Get(nameof(CdpConfig));
                // 数据库配置
                var sConfigData = ConfigContext<CdpConfig, SqlServerConfigService<CdpConfig>>.Current.Get(nameof(CdpConfig));
                
                Console.ReadKey();
            }
        }
    }

    四、总结

      1、定义接口,实现接口,使用上下文类对外提供统一无差别的服务,也是遵循软件系统中设计原则来设计。

      2、对于配置文件的频繁获取并且数据不易变动的,所以在获取配置文件中可以加入缓存的机制,可以减少获取配置文件查询,从缓存获取数据。

      3、配置文件可以是远程的数据库服务器或文件服务器,让分布式系统共享配置文件。

  • 相关阅读:
    【译】x86程序员手册30-8.2 I/O指令
    【译】x86程序员手册29-第8章 输入输出
    【译】x86程序员手册28-7.7任务地址空间
    【译】x86程序员手册27-7.6任务链
    【译】x86程序员手册26-7.5任务切换
    【译】x86程序员手册25-7.1任务状态段
    【译】x86程序员手册23-6.5组合页与段保护
    【译】x86程序员手册24-第7章 多任务
    【译】x86程序员手册22-6.4页级保护
    WPF Blend Grid 布局
  • 原文地址:https://www.cnblogs.com/tuqunfu/p/15587533.html
Copyright © 2020-2023  润新知