抛弃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 { getset; }

        
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(),thisas 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 { getset; }
        
public string DataPre { getset; }
        
public string Provider { getset; }
        
public string AssemblyInfo { getset; }
        
public string DefaultDBName { getset; }

    }
 

       以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开发系列:缓存类信息以及配置文件的处理 一文

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

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

 

posted @ 2010-10-26 16:12  大熊先生|互联网后端技术  阅读(2058)  评论(16编辑  收藏  举报