抛弃ConfigurationManager , 实现面向对象读写配置文件

不知道大家遇到烦人的配置文件读取与操作是怎么处理的呢?

       可能很多很多人都在使用ConfigurationManage这个类来读取配置信息,这在按照需求要求的配置信息比较少的时候是一个非常好的方案。可是如果配置信息非常的多,而且是分好了类的配置信息 ,如果还使用ConfigurationManage就显得有点僵硬了。我们很多时候希望自己开发的逻辑组建化,并且可以对其进行管理,下面我就来提供一个方法来解决配置文件问题。

      首先看看这个类

代码
public   abstract   class  ConfigProvider:ProviderBase
    {
      
        
public   abstract   object  Load( string  typename,  object  settings);

        
public   abstract   void  Save( string  typename,  object  settings);
        
        
public   abstract   string  Location( string  typename);

    }

   有经验的人一眼就可以看出,这是一个provider的基类。那么我们究竟用什么方法来解决我们的问题呢?现在我们回到基类,

object Load(string typename, object settings)   加载配置信息

 void Save(string typename, object settings)     保存配置信息

string Location(string typename)                       提供保存地址

 下面我们来看一个实现类

代码
public   class  XmlConfigProvider : ConfigProvider
    {
        
public   override   object  Load( string  typename,  object  settings)
        {
            
string  _fileName  =  Location(typename);
            
object  returnobject  =   null ;
            
try
            {
                
if  (File.Exists(_fileName))
                {
                    TextReader readertest  =   new  StreamReader(_fileName);
                    XmlSerializer x  =   new  XmlSerializer(settings.GetType());
                    returnobject  =  x.Deserialize(readertest);
                    readertest.Close();
                }
            }
            
catch  (Exception e)
            {
                
throw   new  AdminException( " 读取 " + typename + GlobalInfo.ConfigFileExtendName + " 文件时发生了错误 " ,e);
            }
            
return  returnobject;
        }


        
public   override   void  Save( string  typename,  object  settings)
        {
            
string  _fileName  =  Location(typename);
            
try
            {
                
using  (TextWriter writer  =   new  StreamWriter(_fileName))
                {
                    XmlSerializer x  =   new  XmlSerializer(settings.GetType());
                    x.Serialize(writer, settings);
                    writer.Close();
                }

            }
            
catch  (Exception e)
            {
                
throw   new  AdminException( " 读取 "   +  typename  +  GlobalInfo.ConfigFileExtendName  +   " 文件时发生了错误 " ,e);
            }
        }
        
public   override   string  Location( string  typename)
        {
           
            
string  ss =  GlobalInfo.MapPath( " Config/Common/ "   +  typename  +  GlobalInfo.ConfigFileExtendName) ;
            
return  ss;
        }
    }

       大家注意到我们的上段代码中的异常信息是使用的AdminException,这个异常是一个自定义异常,是为了方便整个系统的管理而设计的。它表示这是一个可以显示异常信息给管理员查看的异常。

至于GlobalInfo.MapPath()这个是一个能够适应在C/S模式与B/S模式下的一个路径计算方法。

 

这个类就是对配置文件类进行简单的序列化之后,由 string Location(string typename)  提供保存地址然后进行保存的例子,在实现细节上大家可以多做修改。

我们可以基于这个Provider设计许多的实现类,具体怎么实现可以自己定制,比如说我希望把配置保存到数据库啊,我希望保存到XML文件啊,我希望保存为.txt文件啊 。 Provider没有提供具体的保存细节,这些细节你可以自己定制开发。我们这里的XmlConfigProvider就是序列化为xml后保存。当然如果这不符合你的系统要求,你可以自己实现具体的Provider

如果你的系统使用了依赖注入等技术的话,那恭喜你,你可以很方便的可以实现低耦合的Provider选择。如果你还对此没有了解的话可以关注一些依赖注入框架 例如spring.net等等    本人也实现了一个依赖注入,在以后的博文中将会陆续发布出来,如果你急于想了解的话可以联系我。

  

 

      这里为了方便大家阅读,我提供一个不是依赖注入的例子。实现一个ConfigService 代码如下:

代码
  public   class  ConfigService
    {
        
public   static  ConfigProvider provider {  get set ; }

        
static  ConfigService()
        {
            provider  = new  XmlConfigProvider();
        }
        
#region  Data Store


        
public   static   object  Load( string  typename,  object  settings)
        {     
             
return  provider.Load(typename, settings);    
        }

        
public   static   void  Save( string  typename,  object  settings)
        { 
            provider.Save(typename, settings);
        }


        
#endregion

    }

         毫无疑问,这是一种紧耦合的方式,我们这里只是做一个例子,所以将就一下。

下面,我们来实现一个基类

代码
public   class  ConfigBase < T >   where  T: class
    {
        
public  T Load()
        {
            
return  ConfigService.Load(GetTypeName(), this as  T;
        }
        
public   void  Save()
        {
            ConfigService.Save(GetTypeName(),  this );          
        }

        
public   string  GetTypeName()
        {
            
return   this .GetType().Name;
        }
    }

至此,解决方案就出来了。从属性的保存,到读取,一条龙服务。方便吗?

什么?还有不知道怎么使用? 我晕!!

     下面看我的例子

代码
 [Serializable]
    
public   class  ORMConfig : ConfigBase < ORMConfig >
    {
        
private   static  ORMConfig _Instance  =  LoadConfig();

        [XmlIgnore]
        
public   static  ORMConfig Instance
        {
            
get  {  return  _Instance; }
        }

        
public   static  ORMConfig LoadConfig()
        {
            
return   new  ORMConfig().Load();
        }


        
public   string  Connection {  get set ; }
        
public   string  DataPre {  get set ; }
        
public   string  Provider {  get set ; }
        
public   string  AssemblyInfo {  get set ; }
        
public   string  DefaultDBName {  get set ; }

    }
 

       以ORMConfig类为例子,我们这里使用的是XmlConfigProvider,所以如果你不想保存哪个属性就直接打上[XmlIgnore]就可以了

如果是你自己开发的 Provider,那就你自己来开发这样的Attribute吧  实现起来也不麻烦。

代码
 ORMConfig configmodel  =   new  ORMConfig();
            configmodel.AssemblyInfo  =   " TestPro " ;
            configmodel.DataPre  =   " HG_ " ;
            configmodel.DefaultDBName  =   " Test_DB " ;
            configmodel.Provider  =   " SqlServer " ;
            configmodel.Connection  =   " Data Source=.;User ID=sa;Password=sasa;Initial Catalog=Test_DB " ;
            configmodel.Save();

       通过上面这一段代码的初始化以后,在以后的运行中,你可以直接操作ORMConfig.Instance.[属性] 来访问你的属性,修改和保存的话继续用上面那一段代码就OK了。如果仅仅是读取配置文件的话,基本上可以脱离任何实现细节了。当然,初始化是必须的!!

       

        我自己在开发ORM的过程中也用到了这样的方法,具体信息请阅读轻量级ORM开发系列:缓存类信息以及配置文件的处理 一文

这里只是提供了一个初稿,更加深入的,全面的还有待实现,这方面有兴趣的可以与我取得联系。 大家可以一起来探讨,实现一个强大的配置文件解决方案。抛砖引玉之作,不足之处,请海涵!

     大家有任何的质疑和疑问都可以与我取得联系。

 

转载于:https://www.cnblogs.com/Creator/archive/2010/10/26/1861509.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值