• 还在用ConfigurationManager这么落伍的方式读写配置文件 ?
  • Kelly 发表于 2016/3/6 12:00:00 | 分类标签: ASP.NET 配置文件
  • 不知道大家遇到烦人的配置文件读取与操作是怎么处理的呢?
     
    可能很多很多人都在使用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开发系列:缓存类信息以及配置文件的处理 一文
     
    这里只是提供了一个初稿,更加深入的,全面的还有待实现,这方面有兴趣的可以与我取得联系。 大家可以一起来探讨,实现一个强大的配置文件解决方案。抛砖引玉之作,不足之处,请海涵!

  • 请您注意

    ·自觉遵守:爱国、守法、自律、真实、文明的原则

    ·尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法规

    ·严禁发表危害国家安全,破坏民族团结、国家宗教政策和社会稳定,含侮辱、诽谤、教唆、淫秽等内容的作品

    ·承担一切因您的行为而直接或间接导致的民事或刑事法律责任

    ·您在编程中国社区新闻评论发表的作品,本网站有权在网站内保留、转载、引用或者删除

    ·参与本评论即表明您已经阅读并接受上述条款

  • 感谢本文作者
  • 作者头像
  • 昵称:Kelly
  • 加入时间:2013/6/13 0:00:00
  • TA的签名
  • 这家伙很懒,虾米都没写
  • +进入TA的空间
  • 以下内容也很赞哦
分享按钮