抛弃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开发系列:缓存类信息以及配置文件的处理 一文
这里只是提供了一个初稿,更加深入的,全面的还有待实现,这方面有兴趣的可以与我取得联系。 大家可以一起来探讨,实现一个强大的配置文件解决方案。抛砖引玉之作,不足之处,请海涵!
大家有任何的质疑和疑问都可以与我取得联系。