您的位置:首页 > 运维架构 > 网站架构

面向服务架构~全局配置文件也面向服务了

2012-06-11 23:16 525 查看
在面向服务中讲配置文件,肯定是要把它与具体领域分离,即它有普遍的一般性。在程序开发过程中,难免会用到一些易变性,全局的常量信息,我们通常的作法是把它们放在Web.config或者自定义的文件中,当然你的配置文件可以是XML,二进制的等等,但一般时候我们选择用XML标准的文件。

看全局配置项目的结构如下:



下面我来介绍一下每个文件的使用:

ConfigFactory它是一个配置文件的工厂类,作用当然就是“从配置文件中生产对象”了,呵呵。(这讲不考虑性能问题)

/// <summary>
/// 配置信息生产工厂
/// </summary>
public class ConfigFactory
{
#region 私有

/// <summary>
/// 配置文件管理类
/// </summary>
static ConfigFilesManager cfm;

#endregion

#region 公开的属性
public T GetConfig<T>() where T : IConfiger
{
string configFilePath = string.Empty;
string filename = typeof(T).Name;

HttpContext context = HttpContext.Current;
string siteVirtrualPath = string.IsNullOrEmpty(ConfigurationManager.AppSettings["SiteVirtrualPath"]) ?
"/" : ConfigurationManager.AppSettings["SiteVirtrualPath"];
if (context != null)
{
configFilePath = context.Server.MapPath(string.Format("{0}/Configs/{1}.Config", siteVirtrualPath, filename));
}
else
{
configFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Configs\{0}.Config", filename);
}

if (!File.Exists(configFilePath))
{
throw new Exception("发生错误: 网站" +
new FileInfo("fileName").DirectoryName
+ "目录下没有正确的.Config文件");
}

cfm = new ConfigFilesManager(configFilePath, typeof(T));
return (T)cfm.LoadConfig();
}
#endregion

}


ConfigFileManager它是一个对文件进行管理的类,它将配置文件反序列化成对象,并提供一段时间后,自动生成新版本的对象,为了线程安全,使用了lock

/// <summary>
/// 基本文件配置信息管理者
/// </summary>
internal class ConfigFilesManager
{

#region 私有
/// <summary>
/// 配置接口
/// </summary>
IConfiger configer;
/// <summary>
/// 锁对象
/// </summary>
object lockHelper = new object();

/// <summary>
/// 配置文件修改时间
/// </summary>
DateTime fileChangeTime;

/// <summary>
/// 配置文件所在路径
/// </summary>
string fileName = null;

Type configType = null;

#endregion

#region 属性

/// <summary>
/// 当前配置类的实例 接口
/// </summary>
internal IConfiger IconfigInfo
{
get { return configer; }
set { configer = value; }
}

/// <summary>
/// 配置文件所在路径
/// </summary>
internal string ConfigFilePath
{
get { return fileName; }

}

#endregion

#region 构造

/// <summary>
/// 初始化文件修改时间和对象实例
/// </summary>
internal ConfigFilesManager(string fileName, Type type)
{
this.fileName = fileName;
//得到配置文件的  改时间
this.configType = type;
fileChangeTime = File.GetLastWriteTime(this.fileName);
this.configer = ConfigSerialize.DeserializeInfo(this.fileName, this.configType);
}

#endregion

#region 配置操作

#region 加载配置类
/// <summary>
/// 加载配置类
/// </summary>
/// <returns></returns>
internal IConfiger LoadConfig()
{
return IconfigInfo as IConfiger;
}
#endregion

#region 重设配置类实例
/// <summary>
/// 重设配置类实例
/// </summary>
/// <returns></returns>
internal IConfiger LoadRealConfig()
{
lock (lockHelper)
{
DateTime newfileChangeTime = File.GetLastWriteTime(this.fileName);
if (!newfileChangeTime.Equals(this.fileChangeTime))
{
IconfigInfo = ConfigSerialize.DeserializeInfo(ConfigFilePath, this.configType);
this.fileChangeTime = newfileChangeTime;
}
}
return IconfigInfo as IConfiger;
}
#endregion

#region 保存配置
/// <summary>
/// 保存配置
/// </summary>
/// <returns></returns>
internal bool SaveConfig()
{
lock (lockHelper)
{
return ConfigSerialize.Serializer(ConfigFilePath, IconfigInfo);
}
}
#endregion

#endregion

}


ConfigSerialize它是一个配置文件序列化和反序列化的功能类,它返回的对象必须是继承自IConfiger接口的对象

/// <summary>
/// 配置序列化操作类
/// </summary>
internal class ConfigSerialize
{
#region 反序列化指定的类

/// <summary>
/// 反序列化指定的类
/// </summary>
/// <param name="configfilepath">config 文件的路径</param>
/// <param name="configtype">相应的类型</param>
/// <returns></returns>
public static IConfiger DeserializeInfo(string path, Type type)
{

IConfiger iconfiginfo;
FileStream fs = null;
try
{
fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
XmlSerializer serializer = new XmlSerializer(type);
iconfiginfo = (IConfiger)serializer.Deserialize(fs);
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (fs != null)
{
fs.Close();
}
}

return iconfiginfo;
}

#endregion

#region 保存(序列化)指定路径下的配置文件

/// <summary>
/// 保存(序列化)指定路径下的配置文件
/// </summary>
/// <param name="configFilePath">指定的配置文件所在的路径(包括文件名)</param>
/// <param name="configinfo">被保存(序列化)的对象</param>
/// <returns></returns>
public static bool Serializer(string path, IConfiger Iconfiginfo)
{
bool succeed = false;
FileStream fs = null;
XmlSerializer serializer = null;
try
{
fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
serializer = new XmlSerializer(Iconfiginfo.GetType());
serializer.Serialize(fs, Iconfiginfo);
//成功则将会返回true
succeed = true;
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (fs != null)
{
fs.Close();
serializer = null;
}
}

return succeed;
}

#endregion

}


IConfiger它是配置信息实体的统一接口,它提供了统一的配置信息操作返回类型,在读取具体配置信息时,只要类型强转换就可以了。

namespace ConfigCache
{
using System;
/// <summary>
/// 配置信息类接口
/// </summary>
public interface IConfiger { }
}


可能有些园友会问,那配置信息的实体呢及配置信息的文件呢?

我要告诉您的是,这些信息是与应用领域相关的,所以不在这个项目中呈现,它要应用到具体的领域项目中,就像这样:



在每一个领域解决方案的WEB项目中,都有一个Configs文件夹,我们的配置信息文件和实体都在这里显示,它们是成对出现的,如WebConfig.cs它是一个网站信息配置的实体,而对应的WebConfig.Config就是它对应的配置信息文件,它们的代码如下:

namespace TEstMv3.Config
{
public class WebConfig : IConfiger
{
public string PageSize { get; set; }
public string CategoryID { get; set; }
}
}


webconfig.config是一个XML标准的文件:

<?xml version="1.0" encoding="utf-8" ?>
<WebConfig>
<PageSize>10</PageSize>
<CategoryID>2</CategoryID>
</WebConfig>


其中<WebConfig>是实体文件的类名,这个要注意一下。

调用用时,可以这样:

new ConfigCache.ConfigFactory().GetConfig<WebConfig>().PageSize;


好了,事实上现在我们就可以工作了,而对于怎么去提升配置文件读取的性能,我会另外写一篇文件的,介请收看。

相关文章:

面向服务架构~全局配置文件也面向服务了

面向服务架构~全局配置文件也面向服务了~续(对性能的优化)

面向服务架构~全局配置文件也面向服务了~再续(引入Cache机制)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐