开发框架之配置管理工具:ConfigManager

昨晚看了看chr的职位,现在的公司都不爱出钱了,哎,职位也少。不过没关系,慢慢来,骑驴找马。

昨天折腾一天项目遗留的bug,潜伏期还真长,不知道当年哪个愣头青写的。测试部老大没在,暂时先不用发版,反正不是什么严重的bug。暂时先让客服去打点吧。

看别人写的代码总是那么的费尽(当然这里包括优雅的代码),如果再不带上注释,头大。不过好在编译器比较牛,大不了跑起来断点了,省得一行一行看。

说到这里想起来两个面试经历,一个是我的,一个是我朋友的。先说我朋友的吧,当时他去某公司面试,面官问他:asp和asp.net的最大区别是什么?  我朋友当然是尽浑身解数讲解,但最后还是被否定。面官给了答案:asp.net比asp方便调试!当时我听了那个寒阿,现在想想还真有道理,要是asp的项目,调个垃圾代码的bug得累死人。

第二个经历是我去某国内知名大型电子商务网站面试经历(为了这公司的脸面就不公布名称了了),其间一道笔试题,我答得比较满意,但后来面官告诉我这写的不对。当时我特虚心问应该怎么做,面官就说应该如此如此。我一听不对,和题上某些细节冲突,于是我就提出了这个冲突。最后,人老先生看了看,把题改了!!然后告诉我,你看,这样就对了。我这个瀑布寒,一脑袋黑线。

 

书归正传,继续说框架。

今儿说的是配置管理。之前说了这些个项目都没有统一的配置管理。没有统一的公共配置源,没有专员维护,以前都是各写各的,最后出现很多同值(同功能),不同命名甚至差异很大。造成在项目维护,重构中困难重重。于是弄了个这个项目,来统一管理配置。其实这个项目不足以单独胜任,还要配合一个配置发布的项目。

另外这个项目也不是完整的功能,可以说是一个模板,继承并实现相关的子类逻辑就好了。winform或者单园池这样的可以直接重载,多园多负载的还是需要回收内存。

先放上代码以供下载。

/Files/rachehunter/ConfigManager.rar

另外可以如下实现:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Text;

using ConfigManager;
using ConfigManager.ConfigVisitor;

using RHTools;
using RHTools.RHUiti;
namespace ZSConfig
{
    
public sealed class ConfigService : BaseConfig
    {
        
private static object lockHelper = new object();

        
private ConfigService()
        {

        }

        
#region Property
        
#region private
        
private string configServiceUrl = String.Empty;
        
/// <summary>
        
/// ConfigServiceUrl
        
/// </summary>
        private string ConfigServiceUrl
        {
            
get { return configServiceUrl; }
        }
        
#endregion

        
#region public
        
private string mySqlDBConfigFilePath = String.Empty;
        
/// <summary>
        
/// MySqlDBConfigFilePath
        
/// </summary>
        public string MySqlDBConfigFilePath
        {
            
get { return mySqlDBConfigFilePath; }
        }

        
private string interfaceConfigFilePath = String.Empty;
        
/// <summary>
        
/// InterfaceConfigFilePath
        
/// </summary>
        public string InterfaceConfigFilePath
        {
            
get { return interfaceConfigFilePath; }
        }

        
private string securityConfigFilePath = String.Empty;
        
/// <summary>
        
/// SecurityConfigFilePath
        
/// </summary>
        public string SecurityConfigFilePath
        {
            
get { return securityConfigFilePath; }
        }

        
private string onlineCacheFilePath = String.Empty;
        
/// <summary>
        
/// OnlineCacheFilePath
        
/// </summary>
        public string OnlineCacheFilePath
        {
            
get { return onlineCacheFilePath; }
        }


        
#endregion
        
#endregion

        
public override void Reload()
        {
            
this.configServiceUrl = base.Read("ConfigServiceUrl");
            IConfigVistior vistiorConfigService 
= null;
            
if (!RHString.StrIsEmtpy(this.configServiceUrl))            
            {
                vistiorConfigService 
= IConfigVistiorFactory.GetInstance(VistiorType.Xml);
                vistiorConfigService.SetConfigFilePath(
this.configServiceUrl);
            }
            
this.mySqlDBConfigFilePath = base.Read(vistiorConfigService, "MySqlDBConfig");
            
this.interfaceConfigFilePath = base.Read(vistiorConfigService, "InterfaceConfig");
            
this.securityConfigFilePath = base.Read(vistiorConfigService, "SecurityConfig");
            
this.onlineCacheFilePath = base.Read(vistiorConfigService, "OnlineCacheFilePath");
        }

        
#region Instance
        
private volatile static ConfigService instance = null;
        
/// <summary>
        
/// 
        
/// </summary>
        public static ConfigService Instance
        {
            
get 
            {
                
if (instance == null)
                {
                    
lock (lockHelper)
                    {
                        
if (instance == null)
                        {
                            instance 
= new ConfigService();
                        }
                    }
                }
                
if (instance == null)
                {
                    RHDebug.ThrowExcetpion(
new ArgumentNullException("ConfigService ConfigManage: unknown error"), true"ConfigService ConfigManage 未知错误");
                }
                
return instance;
            }
        }
        
#endregion
    }
}

 

另外值得说的是这个项目不应局限于配置,也可以做一些其他的缓存。设计思路为单件缓存,监听重载。

附上部分文档:

 

命名空间:ConfigManager.ConfigVisitor

1.  IConfigVistior配置源访问器接口。

void SetConfigFilePath(string path)设定读取的配置文件路径

string ReadConfig(string key) 读取配置节点数据

 

2.  IConfigVistiorFactory配置源访问器工厂。根据枚举值生成配置源访问器实例。

3.  VistiorType配置源访问器枚举。

4.  WebConfigVistior Web.Config访问器。读取AppSettings配置。

5.  XmlConfigVistior Xml配置访问器。

需要Xml配置按以下格式书写。可以读取远程Xml文档

    <?xml version="1.0" encoding="utf-8" ?>

    <Config>

      <test1>value1</test1>

</Config>

 

在使用时需要先调用SetConfigFilePath设置路径,然后再进行读取。

 

命名空间:ConfigManager

6.  BaseConfig 配置管理类的基类。

protected BaseConfig() 载入配置信息,并将本身添加至配置管理列表类实例

protected IConfigVistior WebConfig WebConfig访问器,默认提供WebConfig配置读取,当读取配置失败时也会调用此访问器在WebConfig中查找

protected virtual string GetConfigFilePathFromBaseConfig(string configFile) 从基础配置中获取配置文件的位置。提供从WebConfig中读取Xml配置文件路径节点。

protected string Read(string key) WebConfig配置访问器读取配置

protected string Read(IConfigVistior vistior, string key) 按传入的配置访问器读取配置

public abstract void Reload() 要求实现读取配置的方法

7.  Reloader配置管理类实例的监听者类。

private List<BaseConfig> configManagers配置管理类实例的列表。

public void Reload() 重新载入全部配置。调用每个配置管理类的Reload方法。

public void Add2List(BaseConfig bcm) 将配置管理类实例添加至列表

public static Reloader Loader 配置管理类监听者的唯一实例


其中不论是配置访问器还是管理类都可以自行扩展,当然要有专人来维护。我是不喜欢用反射的,因为反射太消耗效率了,所以我的工厂都不提供反射实例化。如果需要维护则由我负责。虽然会延长工期,增加部分维护量,但我觉得在大项目中这点工作还是值得牺牲的。

转载于:https://www.cnblogs.com/rachehunter/archive/2009/02/04/1383776.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值