init lserp cs 5.0
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using Lskj.DevFx.ExceptionManagement;
|
||||
|
||||
namespace Lskj.DevFx.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置异常
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 在配置里面,能发现的异常都会包装成此类的实例
|
||||
/// </remarks>
|
||||
[Serializable]
|
||||
public class ConfigException : BaseException
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public ConfigException() : base() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="message">异常消息</param>
|
||||
/// <param name="innerException">内部异常</param>
|
||||
public ConfigException(string message, Exception innerException)
|
||||
: base(message, innerException) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="message">异常消息</param>
|
||||
public ConfigException(string message)
|
||||
: base(message) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="errorNo">异常编号</param>
|
||||
/// <param name="message">异常消息</param>
|
||||
public ConfigException(int errorNo, string message)
|
||||
: base(errorNo, message) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="errorNo">异常编号</param>
|
||||
/// <param name="message">异常消息</param>
|
||||
/// <param name="innerException">内部异常</param>
|
||||
public ConfigException(int errorNo, string message, Exception innerException)
|
||||
: base(errorNo, message, innerException) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using Lskj.DevFx.Config.XmlConfig;
|
||||
|
||||
namespace Lskj.DevFx.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// 关于配置的一些实用方法
|
||||
/// </summary>
|
||||
public static class ConfigHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 缺省的XML配置文件查找目录列表
|
||||
/// </summary>
|
||||
public static readonly string[] ConfigFileDefaultSearchPath = {
|
||||
"./", "./../", "./../../", "./../../../",
|
||||
"./../Configuration/", "./../../Configuration/", "./../../../Configuration/",
|
||||
Environment.CurrentDirectory + "/",
|
||||
AppDomain.CurrentDomain.SetupInformation.ApplicationBase
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 验证配置文件路径并返回
|
||||
/// </summary>
|
||||
/// <param name="fileName">配置文件名</param>
|
||||
/// <param name="searchPath">搜索目录列表</param>
|
||||
/// <returns>返回配置文件路径</returns>
|
||||
public static string SearchConfigFile(string fileName, string[] searchPath) {
|
||||
if(File.Exists(fileName)) {
|
||||
return fileName;
|
||||
}
|
||||
if(searchPath == null || searchPath.Length <= 0) {
|
||||
searchPath = ConfigFileDefaultSearchPath;
|
||||
}
|
||||
foreach(string filePath in searchPath) {
|
||||
string fullName = Path.GetFullPath(filePath + fileName);
|
||||
if(File.Exists(fullName)) {
|
||||
return fullName;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找由通配符指定的文件集合
|
||||
/// </summary>
|
||||
/// <param name="filePattern">文件通配符</param>
|
||||
/// <param name="searchPath">搜索目录列表</param>
|
||||
/// <returns>找到的文件列表</returns>
|
||||
public static string[] SearchConfigFileWithPattern(string filePattern, string[] searchPath) {
|
||||
if(searchPath == null || searchPath.Length <= 0) {
|
||||
searchPath = ConfigFileDefaultSearchPath;
|
||||
}
|
||||
List<string> foundFils = new List<string>();
|
||||
foreach(string filePath in searchPath) {
|
||||
string fullPath = Path.GetFullPath(filePath);
|
||||
if(Directory.Exists(fullPath)) {
|
||||
string[] files = Directory.GetFiles(fullPath, filePattern, SearchOption.TopDirectoryOnly);
|
||||
foundFils.AddRange(files);
|
||||
}
|
||||
}
|
||||
return foundFils.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从Xml字符串中生成 <see cref="IConfigSetting"/>
|
||||
/// </summary>
|
||||
/// <param name="xmlString">Xml字符串</param>
|
||||
/// <returns><see cref="IConfigSetting"/></returns>
|
||||
public static IConfigSetting CreateFromXmlString(string xmlString) {
|
||||
XmlNode xmlNode = LoadXmlNodeFromString(xmlString, "/");
|
||||
if(xmlNode is XmlDocument) {
|
||||
xmlNode = ((XmlDocument)xmlNode).DocumentElement;
|
||||
}
|
||||
return XmlConfigSetting.Create(null, xmlNode, true, null, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从Xml文件中生成 <see cref="IConfigSetting"/>
|
||||
/// </summary>
|
||||
/// <param name="xmlFileName">Xml文件</param>
|
||||
/// <returns><see cref="IConfigSetting"/></returns>
|
||||
public static IConfigSetting CreateFromXmlFile(string xmlFileName) {
|
||||
return XmlConfigSetting.Create(xmlFileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从 <see cref="XmlNode"/> 生成 <see cref="IConfigSetting"/>
|
||||
/// </summary>
|
||||
/// <param name="xmlNode"><see cref="XmlNode"/></param>
|
||||
/// <returns><see cref="IConfigSetting"/></returns>
|
||||
public static IConfigSetting CreateFromXmlNode(XmlNode xmlNode) {
|
||||
return XmlConfigSetting.Create(null, xmlNode, true, null, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从资源(Uri)中生成 <see cref="IConfigSetting"/>
|
||||
/// </summary>
|
||||
/// <param name="xmlSource">Uri字符串</param>
|
||||
/// <param name="sourceInType">如果是内嵌资源所在的程序集</param>
|
||||
/// <returns><see cref="IConfigSetting"/></returns>
|
||||
public static IConfigSetting CreateFromXmlSource(string xmlSource, Type sourceInType) {
|
||||
IConfigSetting setting = null;
|
||||
if(xmlSource.StartsWith("res://", true, null)) {
|
||||
string sourceName = xmlSource.Substring(6);
|
||||
Assembly assembly = sourceInType.Assembly;
|
||||
Stream stream = assembly.GetManifestResourceStream(sourceName);
|
||||
if(stream == null) {
|
||||
throw new ConfigException("未找到资源" + xmlSource);
|
||||
}
|
||||
StreamReader sr = new StreamReader(stream);
|
||||
string xmlString = sr.ReadToEnd();
|
||||
setting = CreateFromXmlString(xmlString);
|
||||
} else if(xmlSource.StartsWith("http://", true, null)) {
|
||||
throw new ConfigException("未实现http://");
|
||||
} else {
|
||||
setting = CreateFromXmlFile(xmlSource);
|
||||
}
|
||||
return setting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取XML文件的内容
|
||||
/// </summary>
|
||||
/// <param name="fileName">XML文件名</param>
|
||||
/// <param name="sectionName">对应的XPath</param>
|
||||
/// <param name="rawType">是否不进行任何转换而返回</param>
|
||||
/// <returns>XmlNode</returns>
|
||||
public static XmlNode LoadXmlNodeFromFile(string fileName, string sectionName, bool rawType) {
|
||||
XmlDocument doc = new XmlDocument();
|
||||
LoadXmlFile(doc, fileName);
|
||||
XmlNode xmlNode = doc.SelectSingleNode(sectionName);
|
||||
if(xmlNode != null) {
|
||||
xmlNode = xmlNode.CloneNode(true);
|
||||
}
|
||||
if(!rawType && xmlNode is XmlDocument) {
|
||||
xmlNode = ((XmlDocument)xmlNode).DocumentElement;
|
||||
}
|
||||
return xmlNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分析XML字符串内容
|
||||
/// </summary>
|
||||
/// <param name="xmlString">XML字符串</param>
|
||||
/// <param name="sectionName">对应的XPath</param>
|
||||
/// <returns>XmlNode</returns>
|
||||
public static XmlNode LoadXmlNodeFromString(string xmlString, string sectionName) {
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.LoadXml(xmlString);
|
||||
XmlNode xmlNode = doc.SelectSingleNode(sectionName);
|
||||
if(xmlNode != null) {
|
||||
return xmlNode.CloneNode(true);
|
||||
}
|
||||
return xmlNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 载入XML文件内容
|
||||
/// </summary>
|
||||
/// <param name="doc">XmlDocument</param>
|
||||
/// <param name="fileName">文件名</param>
|
||||
private static void LoadXmlFile(XmlDocument doc, string fileName) {
|
||||
doc.Load(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,521 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using Lskj.DevFx.Utils;
|
||||
|
||||
namespace Lskj.DevFx.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置节实现
|
||||
/// </summary>
|
||||
public abstract class ConfigSetting : IConfigSetting
|
||||
{
|
||||
#region static fields
|
||||
|
||||
/// <summary>
|
||||
/// 配置节另附的文件属性名
|
||||
/// </summary>
|
||||
public const string ConfigFilePropertyName = "configFile";
|
||||
/// <summary>
|
||||
/// 配置节在另附文件的节点名
|
||||
/// </summary>
|
||||
public const string ConfigNodePropertyName = "configNode";
|
||||
/// <summary>
|
||||
/// 配置节实际名称的属性名
|
||||
/// </summary>
|
||||
public const string ConfigNamePropertyName = "name";
|
||||
|
||||
#endregion static fields
|
||||
|
||||
#region constructor
|
||||
|
||||
/// <summary>
|
||||
/// 保护构造方法
|
||||
/// </summary>
|
||||
protected ConfigSetting() {
|
||||
}
|
||||
|
||||
#endregion constructor
|
||||
|
||||
#region fields
|
||||
|
||||
/// <summary>
|
||||
/// 是否只读
|
||||
/// </summary>
|
||||
private bool @readonly;
|
||||
/// <summary>
|
||||
/// 此配置节实际名称
|
||||
/// </summary>
|
||||
private string settingName;
|
||||
/// <summary>
|
||||
/// 配置值
|
||||
/// </summary>
|
||||
protected SettingValue value;
|
||||
/// <summary>
|
||||
/// 父配置节
|
||||
/// </summary>
|
||||
protected ConfigSetting parent;
|
||||
/// <summary>
|
||||
/// 配置属性
|
||||
/// </summary>
|
||||
protected SettingProperty property;
|
||||
/// <summary>
|
||||
/// 子配置节
|
||||
/// </summary>
|
||||
protected ConfigSettingCollection childSettings;
|
||||
/// <summary>
|
||||
/// 配置节命令集合
|
||||
/// </summary>
|
||||
protected ConfigSettingCollection operatorSettings;
|
||||
|
||||
#endregion fields
|
||||
|
||||
#region abstract methods
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置节实例
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected abstract ConfigSetting CreateConfigSetting();
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置值
|
||||
/// </summary>
|
||||
/// <param name="name">配置值名</param>
|
||||
/// <param name="value">配置值</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <returns>SettingValue</returns>
|
||||
protected abstract SettingValue CreateSettingValue(string name, string value, bool @readonly);
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置属性实例
|
||||
/// </summary>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <returns>SettingProperty</returns>
|
||||
protected abstract SettingProperty CreateSettingProperty(bool @readonly);
|
||||
|
||||
/// <summary>
|
||||
/// 转换成字符串
|
||||
/// </summary>
|
||||
/// <param name="sb"><see cref="StringBuilder"/></param>
|
||||
/// <param name="layerIndex">所处层次</param>
|
||||
protected abstract void ToString(StringBuilder sb, int layerIndex);
|
||||
|
||||
#endregion abstract methods
|
||||
|
||||
#region members
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置节实例
|
||||
/// </summary>
|
||||
/// <param name="setting">被复制的配置节</param>
|
||||
/// <param name="deep">是否深度复制</param>
|
||||
/// <returns>配置节</returns>
|
||||
protected virtual ConfigSetting CreateConfigSetting(ConfigSetting setting, bool deep) {
|
||||
ConfigSetting newSetting = this.CreateConfigSetting();
|
||||
newSetting.@readonly = setting.ReadOnly;
|
||||
newSetting.settingName = setting.settingName;
|
||||
if (deep) {
|
||||
newSetting.value = setting.Value.Clone();
|
||||
newSetting.property = setting.Property.Clone(this.@readonly, deep);
|
||||
newSetting.childSettings = setting.childSettings.Clone();
|
||||
newSetting.operatorSettings = setting.operatorSettings.Clone();
|
||||
} else {
|
||||
newSetting.value = setting.Value;
|
||||
newSetting.property = setting.Property;
|
||||
newSetting.childSettings = setting.childSettings;
|
||||
newSetting.operatorSettings = setting.operatorSettings;
|
||||
}
|
||||
return newSetting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前配置节是否只读
|
||||
/// </summary>
|
||||
public virtual bool ReadOnly {
|
||||
get { return this.@readonly; }
|
||||
protected set { this.@readonly = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 此配置节的名
|
||||
/// </summary>
|
||||
public virtual string Name {
|
||||
get { return this.Value.Name; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 此配置节实际名称
|
||||
/// </summary>
|
||||
public virtual string SettingName {
|
||||
get {
|
||||
if (!string.IsNullOrEmpty(this.settingName)) {
|
||||
return this.settingName;
|
||||
} else {
|
||||
return this.Name;
|
||||
}
|
||||
}
|
||||
protected set { this.settingName = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 此配置节的名/值
|
||||
/// </summary>
|
||||
public virtual SettingValue Value {
|
||||
get { return this.value; }
|
||||
set {
|
||||
if(this.ReadOnly) {
|
||||
throw new ConfigException("配置节只读");
|
||||
}
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 包含此配置节的父配置节
|
||||
/// </summary>
|
||||
public virtual ConfigSetting Parent {
|
||||
get { return this.parent; }
|
||||
set { this.parent = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 此配置节包含的子配置节数目
|
||||
/// </summary>
|
||||
public virtual int Children {
|
||||
get { return this.childSettings.Count; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置节属性
|
||||
/// </summary>
|
||||
public virtual SettingProperty Property {
|
||||
get { return this.property; }
|
||||
set {
|
||||
if(this.ReadOnly) {
|
||||
throw new ConfigException("配置节只读");
|
||||
}
|
||||
this.property = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取此配置节的另附文件
|
||||
/// </summary>
|
||||
public virtual string ConfigFile {
|
||||
get { return this.Property.TryGetPropertyValue(ConfigFilePropertyName); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取此配置节另附文件中的节点
|
||||
/// </summary>
|
||||
public virtual string ConfigNode {
|
||||
get { return this.Property.TryGetPropertyValue(ConfigNodePropertyName); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 此节是否为配置节命令
|
||||
/// </summary>
|
||||
protected virtual ConfigSettingOperator SettingOperator {
|
||||
get { return Converting.StringToEnum<ConfigSettingOperator>(this.SettingName); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取/设置子配置节
|
||||
/// </summary>
|
||||
/// <param name="childSettingName">子配置节名</param>
|
||||
/// <remarks>
|
||||
/// 如果不存在,将返回<c>null</c><br />
|
||||
/// 如果设置时存在相同的节,则替换
|
||||
/// </remarks>
|
||||
public virtual ConfigSetting this[string childSettingName] {
|
||||
get { return this.childSettings[childSettingName]; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取子配置节
|
||||
/// </summary>
|
||||
/// <param name="childSettingIndex">子配置节顺序</param>
|
||||
/// <remarks>
|
||||
/// 如果不存在,将返回null
|
||||
/// </remarks>
|
||||
public virtual ConfigSetting this[int childSettingIndex] {
|
||||
get { return this.childSettings[childSettingIndex]; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有子配置节
|
||||
/// </summary>
|
||||
/// <returns>配置节数组</returns>
|
||||
public virtual ConfigSetting[] GetChildSettings() {
|
||||
return this.childSettings.CopyToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按XPath方式获取配置节
|
||||
/// </summary>
|
||||
/// <param name="xpath">XPath</param>
|
||||
/// <returns>配置节</returns>
|
||||
/// <remarks>
|
||||
/// XPath为类似XML的XPath,形如<c>framework/modules/module"</c><br />
|
||||
/// 如果有相同的配置节,则返回第一个配置节
|
||||
/// </remarks>
|
||||
public virtual ConfigSetting GetChildSetting(string xpath) {
|
||||
string[] settingName = null;
|
||||
if(xpath != null) {
|
||||
if(xpath.StartsWith("/")) {
|
||||
xpath = xpath.Substring(1);
|
||||
}
|
||||
settingName = xpath.Split('/');
|
||||
}
|
||||
return this.GetChildSetting(settingName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按多级方式获取配置节
|
||||
/// </summary>
|
||||
/// <param name="settingName">多级的配置节名</param>
|
||||
/// <returns>配置节</returns>
|
||||
/// <remarks>
|
||||
/// 多级的配置节名,形如有如下配置:
|
||||
/// <code>
|
||||
/// <app1>
|
||||
/// <app2>
|
||||
/// <app3></app3>
|
||||
/// </app2>
|
||||
/// </app1>
|
||||
/// </code>
|
||||
/// 则按顺序传入,比如<c>GetChildSetting("app1", "app2", "app3")</c>,此时返回名为<c>app3</c>的配置节<br />
|
||||
/// "."表示当前配置节,".."表示上级配置节
|
||||
/// </remarks>
|
||||
public virtual ConfigSetting GetChildSetting(params string[] settingName) {
|
||||
ConfigSetting setting = this;
|
||||
if(settingName != null && settingName.Length > 0) {
|
||||
for(int i = 0; setting != null && i < settingName.Length; i++) {
|
||||
string name = settingName[i];
|
||||
switch (name) {
|
||||
case ".":
|
||||
case null:
|
||||
break;
|
||||
case "..":
|
||||
setting = setting.parent;
|
||||
break;
|
||||
default:
|
||||
setting = setting[name];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return setting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 克隆此配置节
|
||||
/// </summary>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <param name="deep">是否深层次的克隆</param>
|
||||
/// <returns>配置节</returns>
|
||||
public virtual ConfigSetting Clone(bool @readonly, bool deep) {
|
||||
ConfigSetting setting = this.CreateConfigSetting(this, deep);
|
||||
setting.@readonly = @readonly;
|
||||
return setting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 克隆此配置节
|
||||
/// </summary>
|
||||
/// <returns>配置节</returns>
|
||||
public virtual ConfigSetting Clone() {
|
||||
return this.Clone(this.ReadOnly, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 合并配置节
|
||||
/// </summary>
|
||||
/// <param name="setting">需被合并的配置节</param>
|
||||
/// <returns>合并后的配置节</returns>
|
||||
public virtual ConfigSetting Merge(ConfigSetting setting) {
|
||||
if(setting == null || string.Compare(this.Name, setting.Name, true) != 0) {
|
||||
return this;
|
||||
}
|
||||
this.Property.Merge(setting.Property);
|
||||
this.value = setting.Value.Clone(this.ReadOnly);
|
||||
|
||||
foreach(ConfigSetting configSetting in setting.operatorSettings.Values) {
|
||||
this.operatorSettings.Add(configSetting).Parent = this;
|
||||
}
|
||||
|
||||
Compile(this, setting.operatorSettings);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编译本配置节,将执行一些配置命令,具有配置命令的配置节需执行本方法后才可以使用
|
||||
/// </summary>
|
||||
/// <param name="current">当前配置节</param>
|
||||
/// <param name="settings">配置命令集合</param>
|
||||
/// <returns>编译后的配置节</returns>
|
||||
protected static ConfigSetting Compile(ConfigSetting current, ConfigSettingCollection settings) {
|
||||
ConfigSettingCollection currentSettings = current.childSettings;
|
||||
if (settings.Count > 0) {
|
||||
for (int i = 0; i < settings.Count; i++) {
|
||||
ConfigSetting setting = settings[i];
|
||||
switch(setting.SettingOperator) {
|
||||
case ConfigSettingOperator.Add:
|
||||
if (currentSettings.Contains(setting.Name)) {
|
||||
throw new ConfigException(string.Format("已存在子配置节 {0}", setting.Name));
|
||||
} else {
|
||||
currentSettings.Add(setting).Parent = current;
|
||||
}
|
||||
break;
|
||||
case ConfigSettingOperator.Remove:
|
||||
currentSettings.Remove(setting.Name);
|
||||
break;
|
||||
case ConfigSettingOperator.Move:
|
||||
ConfigSetting moveSetting = currentSettings[setting.Name];
|
||||
if(moveSetting != null) {
|
||||
currentSettings.Remove(moveSetting.Name);
|
||||
currentSettings.Add(moveSetting);
|
||||
}
|
||||
break;
|
||||
case ConfigSettingOperator.Clear:
|
||||
currentSettings.Clear();
|
||||
break;
|
||||
case ConfigSettingOperator.Update:
|
||||
if (currentSettings.Contains(setting.Name)) {
|
||||
currentSettings[setting.Name].Merge(setting);
|
||||
}
|
||||
break;
|
||||
case ConfigSettingOperator.Set:
|
||||
if (currentSettings.Contains(setting.Name)) {
|
||||
currentSettings[setting.Name].Merge(setting);
|
||||
} else {
|
||||
currentSettings.Add(setting).Parent = current;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (currentSettings.Contains(setting.Name)) {
|
||||
currentSettings[setting.Name].Merge(setting);
|
||||
} else {
|
||||
currentSettings.Add(setting).Parent = current;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取根配置节
|
||||
/// </summary>
|
||||
/// <returns>配置节</returns>
|
||||
public virtual ConfigSetting GetRootSetting() {
|
||||
ConfigSetting root = this;
|
||||
while(root.parent != null) {
|
||||
root = root.parent;
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换成字符串格式
|
||||
/// </summary>
|
||||
/// <returns>字符串</returns>
|
||||
public override string ToString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
this.ToString(sb, 0);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
#endregion members
|
||||
|
||||
#region ICloneable Members
|
||||
|
||||
object ICloneable.Clone() {
|
||||
return this.Clone(this.ReadOnly, true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IConfigSetting Members
|
||||
|
||||
bool IConfigSetting.ReadOnly {
|
||||
get { return this.ReadOnly; }
|
||||
}
|
||||
|
||||
string IConfigSetting.Name {
|
||||
get { return this.Name; }
|
||||
}
|
||||
|
||||
string IConfigSetting.SettingName {
|
||||
get { return this.SettingName; }
|
||||
}
|
||||
|
||||
ISettingValue IConfigSetting.Value {
|
||||
get { return this.Value; }
|
||||
}
|
||||
|
||||
IConfigSetting IConfigSetting.Parent {
|
||||
get { return this.Parent; }
|
||||
}
|
||||
|
||||
int IConfigSetting.Children {
|
||||
get { return this.Children; }
|
||||
}
|
||||
|
||||
ISettingProperty IConfigSetting.Property {
|
||||
get { return this.Property; }
|
||||
}
|
||||
|
||||
IConfigSetting IConfigSetting.this[string childSettingName] {
|
||||
get { return this[childSettingName]; }
|
||||
}
|
||||
|
||||
IConfigSetting IConfigSetting.this[int childSettingIndex] {
|
||||
get { return this[childSettingIndex]; }
|
||||
}
|
||||
|
||||
IConfigSetting[] IConfigSetting.GetChildSettings() {
|
||||
return this.GetChildSettings();
|
||||
}
|
||||
|
||||
IConfigSetting IConfigSetting.GetChildSetting(string xpath) {
|
||||
return this.GetChildSetting(xpath);
|
||||
}
|
||||
|
||||
IConfigSetting IConfigSetting.GetChildSetting(params string[] settingName) {
|
||||
return this.GetChildSetting(settingName);
|
||||
}
|
||||
|
||||
IConfigSetting IConfigSetting.Clone(bool @readonly, bool deep) {
|
||||
return this.Clone(@readonly, deep);
|
||||
}
|
||||
|
||||
IConfigSetting IConfigSetting.GetRootSetting() {
|
||||
return this.GetRootSetting();
|
||||
}
|
||||
|
||||
void IConfigSetting.Merge(IConfigSetting setting) {
|
||||
this.Merge((ConfigSetting)setting);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using Lskj.DevFx.Utils;
|
||||
|
||||
namespace Lskj.DevFx.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置节集合
|
||||
/// </summary>
|
||||
public class ConfigSettingCollection : CollectionBase<ConfigSetting>
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造方法
|
||||
/// </summary>
|
||||
/// <param name="uniqueKey">键值是否唯一</param>
|
||||
public ConfigSettingCollection(bool uniqueKey) : base(uniqueKey) { }
|
||||
|
||||
/// <summary>
|
||||
/// 添加配置节
|
||||
/// </summary>
|
||||
/// <param name="setting">配置节</param>
|
||||
/// <returns>配置节</returns>
|
||||
public virtual ConfigSetting Add(ConfigSetting setting) {
|
||||
this.Add(setting.Name, setting);
|
||||
return setting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加/替换配置节(如果存在则替换)
|
||||
/// </summary>
|
||||
/// <param name="setting">配置节</param>
|
||||
public virtual ConfigSetting Set(ConfigSetting setting) {
|
||||
Converting.StringToEnum<ConfigSettingOperator>("");
|
||||
this.Set(setting.Name, setting);
|
||||
return setting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 深度复制集合
|
||||
/// </summary>
|
||||
/// <returns>复制后的集合</returns>
|
||||
public virtual ConfigSettingCollection Clone() {
|
||||
ConfigSettingCollection collection = new ConfigSettingCollection(this.UniqueKey);
|
||||
foreach(ConfigSetting setting in this.Values) {
|
||||
collection.Add(setting.Clone()).Parent = setting.Parent;
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
namespace Lskj.DevFx.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置节命令
|
||||
/// </summary>
|
||||
public enum ConfigSettingOperator
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加配置节
|
||||
/// </summary>
|
||||
Add = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 移除配置节
|
||||
/// </summary>
|
||||
Remove,
|
||||
|
||||
/// <summary>
|
||||
/// 移动配置节
|
||||
/// </summary>
|
||||
Move,
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有配置节
|
||||
/// </summary>
|
||||
Clear,
|
||||
|
||||
/// <summary>
|
||||
/// 更新(合并)配置节(如果不存在,则忽略此命令)
|
||||
/// </summary>
|
||||
Update,
|
||||
|
||||
/// <summary>
|
||||
/// 设置配置节,如果存在则合并,否则添加
|
||||
/// </summary>
|
||||
Set,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.Configuration;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using Lskj.DevFx.Data;
|
||||
|
||||
namespace Lskj.DevFx.Config.DotNetConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置元素基础类,从<see cref="ConfigurationElement"/>派生
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>此类对基类<see cref="ConfigurationElement"/>做了些修改,允许未定义的属性存在</para>
|
||||
/// <para>派生类如果要允许未定义的属性,则必须重写<see cref="BaseConfigurationElement.OnDeserializeUnrecognizedFlag"/></para>
|
||||
/// </remarks>
|
||||
public abstract class BaseConfigurationElement : ConfigurationElement
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取一个值,该值指示反序列化过程中是否遇到未知属性
|
||||
/// </summary>
|
||||
/// <param name="name">无法识别的属性的名称</param>
|
||||
/// <param name="value">无法识别的属性的值</param>
|
||||
/// <returns>如果反序列化过程中遇到未知属性,则为<c>true</c></returns>
|
||||
protected override bool OnDeserializeUnrecognizedAttribute(string name, string value) {
|
||||
this.unkownProperties.Add(name, value);
|
||||
return this.OnDeserializeUnrecognizedFlag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个值,该值指示反序列化过程中是否遇到未知元素
|
||||
/// </summary>
|
||||
/// <param name="elementName">未知的子元素的名称</param>
|
||||
/// <param name="reader">用于反序列化的 <seealso cref="XmlReader"/> 对象</param>
|
||||
/// <returns>如果反序列化过程中遇到未知元素,则为 true</returns>
|
||||
protected override bool OnDeserializeUnrecognizedElement(string elementName, XmlReader reader) {
|
||||
return this.OnDeserializeUnrecognizedFlag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否遇到未知的属性或元素
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>派生类如果要允许未定义的属性,则必须重写本属性</para>
|
||||
/// </remarks>
|
||||
protected virtual bool OnDeserializeUnrecognizedFlag {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 本元素对应的Xml
|
||||
/// </summary>
|
||||
public virtual string OuterXml {
|
||||
get { return this.outerXml; }
|
||||
}
|
||||
|
||||
private string outerXml;
|
||||
private NameValueCollection unkownProperties = new NameValueCollection();
|
||||
|
||||
/// <summary>
|
||||
/// 读取配置文件中的 XML
|
||||
/// </summary>
|
||||
/// <param name="reader">在配置文件中进行读取操作的 <seealso cref="XmlReader"/></param>
|
||||
/// <param name="serializeCollectionKey">为 <c>true</c>,则只序列化集合的键属性;否则为 <c>false</c></param>
|
||||
protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey) {
|
||||
FieldInfo field = reader.GetType().GetField("_rawXml", FieldMemberInfo.FieldBindingFlags);
|
||||
this.outerXml = (string)field.GetValue(reader);
|
||||
base.DeserializeElement(reader, serializeCollectionKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取未定义的属性值
|
||||
/// </summary>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
/// <returns>属性值</returns>
|
||||
public virtual string GetPropertyValue(string propertyName) {
|
||||
return this.unkownProperties[propertyName];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取未定义的属性值
|
||||
/// </summary>
|
||||
/// <typeparam name="T">属性值类型</typeparam>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
/// <returns>属性值</returns>
|
||||
public virtual T GetPropertyValue<T>(string propertyName) {
|
||||
return this.GetPropertyValue(propertyName, default(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取未定义的属性值
|
||||
/// </summary>
|
||||
/// <typeparam name="T">属性值类型</typeparam>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
/// <param name="defaultValue">如果此属性不存在需提供的缺省值</param>
|
||||
/// <returns>属性值</returns>
|
||||
public virtual T GetPropertyValue<T>(string propertyName, T defaultValue) {
|
||||
string propertyValue = this.GetPropertyValue(propertyName);
|
||||
T returnValue = defaultValue;
|
||||
if (!string.IsNullOrEmpty(propertyValue)) {
|
||||
returnValue = (T)Convert.ChangeType(propertyValue, typeof(T));
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测指定的属性是否存在
|
||||
/// </summary>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
/// <returns>是否存在</returns>
|
||||
public virtual bool CheckPropertyExists(string propertyName) {
|
||||
return this.unkownProperties[propertyName] != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System.Configuration;
|
||||
|
||||
namespace Lskj.DevFx.Config.DotNetConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 基础的配置元素集合(抽象),继承自 <seealso cref="ConfigurationElementCollection"/>
|
||||
/// </summary>
|
||||
public abstract class BaseConfigurationElementCollection : ConfigurationElementCollection
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得元素的键
|
||||
/// </summary>
|
||||
/// <param name="element">配置元素</param>
|
||||
/// <returns>键</returns>
|
||||
protected override object GetElementKey(ConfigurationElement element) {
|
||||
return element.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System.Configuration;
|
||||
|
||||
namespace Lskj.DevFx.Config.DotNetConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置集合(泛型)
|
||||
/// </summary>
|
||||
/// <typeparam name="T">集合元素类型</typeparam>
|
||||
public class ConfigCollection<T> : BaseConfigurationElementCollection where T : ConfigurationElement, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// 按索引方式获取元素
|
||||
/// </summary>
|
||||
/// <param name="index">索引</param>
|
||||
/// <returns>元素</returns>
|
||||
public virtual T this[int index] {
|
||||
get { return (T)this.BaseGet(index); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按键值方式获取元素
|
||||
/// </summary>
|
||||
/// <param name="key">键值</param>
|
||||
/// <returns>元素</returns>
|
||||
public virtual T this[object key] {
|
||||
get { return (T)this.BaseGet(key); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 集合转换成数组
|
||||
/// </summary>
|
||||
/// <returns>元素数组</returns>
|
||||
public virtual T[] ToArray() {
|
||||
T[] values = new T[this.Count];
|
||||
this.CopyTo(values, 0);
|
||||
return values;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建新元素
|
||||
/// </summary>
|
||||
/// <returns>新元素</returns>
|
||||
protected override ConfigurationElement CreateNewElement() {
|
||||
return new T();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Web;
|
||||
using System.Web.Configuration;
|
||||
using Lskj.DevFx.Utils;
|
||||
|
||||
namespace Lskj.DevFx.Config.DotNetConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置组(依赖 .NET的配置架构)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <code>
|
||||
/// <configSections>
|
||||
/// <sectionGroup name="Lskj.devfx" type="Lskj.DevFx.Config.DotNetConfig.GroupHandler, Lskj.DevFx.BaseFx">
|
||||
/// <section name="mail" type="Lskj.DevFx.Utils.Mail.Config.SectionHandler, Lskj.DevFx.BaseFx" />
|
||||
/// ......
|
||||
/// </sectionGroup>
|
||||
/// </configSections>
|
||||
///
|
||||
/// ......
|
||||
///
|
||||
/// <Lskj.devfx>
|
||||
/// <mail>
|
||||
/// <smtpSetting server="" port="" userName="" password="" />
|
||||
/// </mail>
|
||||
/// </Lskj.devfx>
|
||||
/// ......
|
||||
/// </code>
|
||||
/// </remarks>
|
||||
public class GroupHandler : ConfigurationSectionGroup
|
||||
{
|
||||
private static GroupHandler instance;
|
||||
private static bool isInit;
|
||||
private static bool isWebApp;
|
||||
private static Dictionary<Type, ConfigurationSection> sectionCache;
|
||||
private static readonly object lockObject = new object();
|
||||
|
||||
private static void Init(bool throwOnError) {
|
||||
if (isInit) {
|
||||
return;
|
||||
}
|
||||
Configuration config;
|
||||
if (HttpContext.Current != null) {
|
||||
isWebApp = true;
|
||||
config = WebConfigurationManager.OpenWebConfiguration(HttpContext.Current.Request.ApplicationPath);
|
||||
} else {
|
||||
isWebApp = false;
|
||||
config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
|
||||
}
|
||||
foreach (string key in config.SectionGroups.Keys) {
|
||||
ConfigurationSectionGroup csg = config.SectionGroups[key];
|
||||
if(csg == null || string.IsNullOrEmpty(csg.Type)) {
|
||||
continue;
|
||||
}
|
||||
Type csgType = TypeHelper.CreateType(csg.Type, false);
|
||||
if (csgType == typeof(GroupHandler)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sectionCache = new Dictionary<Type, ConfigurationSection>();
|
||||
|
||||
if (instance == null) {
|
||||
isInit = true;
|
||||
if (throwOnError) {
|
||||
throw new ConfigException("配置组未正确配置");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (ConfigurationSection section in instance.Sections) {
|
||||
string sectionTypeName = section.SectionInformation.Type;
|
||||
string sectionName = section.SectionInformation.SectionName;
|
||||
Type sectionType = TypeHelper.CreateType(sectionTypeName, false);
|
||||
object objectSection;
|
||||
if (isWebApp) {
|
||||
objectSection = WebConfigurationManager.GetSection(sectionName);
|
||||
} else {
|
||||
objectSection = ConfigurationManager.GetSection(sectionName);
|
||||
}
|
||||
if (objectSection != null) {
|
||||
sectionCache.Add(sectionType, (ConfigurationSection)objectSection);
|
||||
}
|
||||
}
|
||||
|
||||
isInit = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前配置组的实例(单件)
|
||||
/// </summary>
|
||||
public static GroupHandler Instance {
|
||||
get { return instance; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取配置节(泛型)
|
||||
/// </summary>
|
||||
/// <typeparam name="T">配置节类型</typeparam>
|
||||
/// <returns>配置节</returns>
|
||||
public static T GetSection<T>() where T : ConfigurationSection {
|
||||
return GetSection<T>(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取配置节(泛型)
|
||||
/// </summary>
|
||||
/// <typeparam name="T">配置节类型</typeparam>
|
||||
/// <param name="throwOnError">如果配置组未配置是否抛出异常</param>
|
||||
/// <returns>配置节</returns>
|
||||
public static T GetSection<T>(bool throwOnError) where T : ConfigurationSection {
|
||||
if (!isInit) {
|
||||
lock (lockObject) {
|
||||
if (!isInit) {
|
||||
Init(throwOnError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Type type = typeof(T);
|
||||
ConfigurationSection sectionObject;
|
||||
sectionCache.TryGetValue(type, out sectionObject);
|
||||
return sectionObject as T;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造方法
|
||||
/// </summary>
|
||||
protected GroupHandler() {
|
||||
instance = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System.Configuration;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using Lskj.DevFx.Data;
|
||||
|
||||
namespace Lskj.DevFx.Config.DotNetConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置节基础处理类,继承自 <see cref="ConfigurationSection"/>
|
||||
/// </summary>
|
||||
/// <typeparam name="T">派生类</typeparam>
|
||||
/// <remarks>
|
||||
/// 注意与 <see cref="BaseConfigurationElement"/> 的区别
|
||||
/// </remarks>
|
||||
public abstract class SectionBaseHandler<T> : ConfigurationSection where T : SectionBaseHandler<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前配置节实例
|
||||
/// </summary>
|
||||
public static T Current {
|
||||
get { return GroupHandler.GetSection<T>(false); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个值,该值指示反序列化过程中是否遇到未知属性
|
||||
/// </summary>
|
||||
/// <param name="name">无法识别的属性的名称</param>
|
||||
/// <param name="value">无法识别的属性的值</param>
|
||||
/// <returns>如果反序列化过程中遇到未知属性,则为<c>true</c></returns>
|
||||
protected override bool OnDeserializeUnrecognizedAttribute(string name, string value) {
|
||||
return this.OnDeserializeUnrecognizedFlag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个值,该值指示反序列化过程中是否遇到未知元素
|
||||
/// </summary>
|
||||
/// <param name="elementName">未知的子元素的名称</param>
|
||||
/// <param name="reader">用于反序列化的 <seealso cref="XmlReader"/> 对象</param>
|
||||
/// <returns>如果反序列化过程中遇到未知元素,则为 true</returns>
|
||||
protected override bool OnDeserializeUnrecognizedElement(string elementName, XmlReader reader) {
|
||||
return this.OnDeserializeUnrecognizedFlag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否遇到未知的属性或元素
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>派生类如果要允许未定义的属性,则必须重写本属性</para>
|
||||
/// </remarks>
|
||||
protected virtual bool OnDeserializeUnrecognizedFlag {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 本配置节对应的Xml
|
||||
/// </summary>
|
||||
public virtual string OuterXml {
|
||||
get { return this.outerXml; }
|
||||
}
|
||||
|
||||
private string outerXml;
|
||||
|
||||
/// <summary>
|
||||
/// 读取配置文件中的 XML
|
||||
/// </summary>
|
||||
/// <param name="reader">在配置文件中进行读取操作的 <seealso cref="XmlReader"/></param>
|
||||
/// <param name="serializeCollectionKey">为 <c>true</c>,则只序列化集合的键属性;否则为 <c>false</c></param>
|
||||
protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey) {
|
||||
FieldInfo field = reader.GetType().GetField("_rawXml", FieldMemberInfo.FieldBindingFlags);
|
||||
this.outerXml = (string)field.GetValue(reader);
|
||||
base.DeserializeElement(reader, serializeCollectionKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace NOVA.DevFx.ExceptionManagement
|
||||
{
|
||||
/// <summary>
|
||||
/// 异常模块异常,框架的基础异常类,所有的异常请从本类派生
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class BaseException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public BaseException() : this(0, null, null) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="message">异常消息</param>
|
||||
/// <param name="innerException">内部异常</param>
|
||||
public BaseException(string message, Exception innerException) : this(0, message, innerException) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="message">异常消息</param>
|
||||
public BaseException(string message) : this(0, message) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="errorNo">异常编号</param>
|
||||
/// <param name="message">异常消息</param>
|
||||
public BaseException(int errorNo, string message) : this(errorNo, message, null) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="errorNo">异常编号</param>
|
||||
/// <param name="message">异常消息</param>
|
||||
/// <param name="innerException">内部异常</param>
|
||||
public BaseException(int errorNo, string message, Exception innerException) : base(message, innerException) {
|
||||
this.errorNo = errorNo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异常编号
|
||||
/// </summary>
|
||||
protected int errorNo;
|
||||
|
||||
/// <summary>
|
||||
/// 异常编号
|
||||
/// </summary>
|
||||
public int ErrorNo {
|
||||
get { return this.errorNo; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找原始的异常
|
||||
/// </summary>
|
||||
/// <param name="e">异常</param>
|
||||
/// <returns>原始的异常</returns>
|
||||
public static Exception FindSourceException(Exception e) {
|
||||
Exception e1 = e;
|
||||
while(e1 != null) {
|
||||
e = e1;
|
||||
e1 = e1.InnerException;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从异常树种查找指定类型的异常
|
||||
/// </summary>
|
||||
/// <param name="e">异常</param>
|
||||
/// <param name="expectedExceptionType">期待的异常类型</param>
|
||||
/// <returns>所要求的异常,如果找不到,返回null</returns>
|
||||
public static Exception FindSourceException(Exception e, Type expectedExceptionType) {
|
||||
while(e != null) {
|
||||
if(e.GetType() == expectedExceptionType) {
|
||||
return e;
|
||||
}
|
||||
e = e.InnerException;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Lskj.DevFx.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置节接口
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 形如下面的XML节表示一个配置节:
|
||||
/// <code>
|
||||
/// <app my="myProperty">myValue</app>
|
||||
/// </code>
|
||||
/// 此时,<c>Name="app"</c>,Value的值为"myValue",Property的值为"myProperty"
|
||||
/// </remarks>
|
||||
public interface IConfigSetting : ICloneable
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前配置节是否只读
|
||||
/// </summary>
|
||||
bool ReadOnly { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 此配置节的名
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 此配置节实际名称
|
||||
/// </summary>
|
||||
string SettingName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 此配置节的名/值
|
||||
/// </summary>
|
||||
ISettingValue Value { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 包含此配置节的父配置节
|
||||
/// </summary>
|
||||
IConfigSetting Parent { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 此配置节包含的子配置节数目
|
||||
/// </summary>
|
||||
int Children { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 配置节属性
|
||||
/// </summary>
|
||||
ISettingProperty Property { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取子配置节
|
||||
/// </summary>
|
||||
/// <param name="childSettingName">子配置节名</param>
|
||||
/// <remarks>
|
||||
/// 如果不存在,将返回<c>null</c>
|
||||
/// </remarks>
|
||||
IConfigSetting this[string childSettingName] { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取子配置节
|
||||
/// </summary>
|
||||
/// <param name="childSettingIndex">子配置节顺序</param>
|
||||
/// <remarks>
|
||||
/// 如果不存在,将返回null
|
||||
/// </remarks>
|
||||
IConfigSetting this[int childSettingIndex] { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有子配置节
|
||||
/// </summary>
|
||||
/// <returns>配置节数组</returns>
|
||||
IConfigSetting[] GetChildSettings();
|
||||
|
||||
/// <summary>
|
||||
/// 按XPath方式获取配置节
|
||||
/// </summary>
|
||||
/// <param name="xpath">XPath</param>
|
||||
/// <returns>配置节</returns>
|
||||
/// <remarks>
|
||||
/// XPath为类似XML的XPath,形如<c>framework/modules"</c><br />
|
||||
/// 如果有相同的配置节,则返回第一个配置节
|
||||
/// </remarks>
|
||||
IConfigSetting GetChildSetting(string xpath);
|
||||
|
||||
/// <summary>
|
||||
/// 按多级方式获取配置节
|
||||
/// </summary>
|
||||
/// <param name="settingName">多级的配置节名</param>
|
||||
/// <returns>配置节</returns>
|
||||
/// <remarks>
|
||||
/// 多级的配置节名,形如有如下配置:
|
||||
/// <code>
|
||||
/// <app1>
|
||||
/// <app2>
|
||||
/// <app3></app3>
|
||||
/// </app2>
|
||||
/// </app1>
|
||||
/// </code>
|
||||
/// 则按顺序传入,比如<c>GetChildSetting("app1", "app2", "app3")</c>,此时返回名为<c>app3</c>的配置节
|
||||
/// </remarks>
|
||||
IConfigSetting GetChildSetting(params string[] settingName);
|
||||
|
||||
/// <summary>
|
||||
/// 获取根配置节
|
||||
/// </summary>
|
||||
/// <returns>配置节</returns>
|
||||
IConfigSetting GetRootSetting();
|
||||
|
||||
/// <summary>
|
||||
/// 合并配置节
|
||||
/// </summary>
|
||||
/// <param name="setting">被合并的配置节</param>
|
||||
void Merge(IConfigSetting setting);
|
||||
|
||||
/// <summary>
|
||||
/// 克隆此配置节
|
||||
/// </summary>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <param name="deep">是否深层次的克隆</param>
|
||||
/// <returns>配置节</returns>
|
||||
IConfigSetting Clone(bool @readonly, bool deep);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Lskj.DevFx.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置节属性接口
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 形如下面的XML节表示一个配置节:
|
||||
/// <code>
|
||||
/// <app my="myProperty">myValue</app>
|
||||
/// </code>
|
||||
/// 此时,<c>Name="app"</c>,Value的值为"myValue",Property的值为"myProperty"
|
||||
/// </remarks>
|
||||
public interface ISettingProperty : ICloneable
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前配置节属性是否只读
|
||||
/// </summary>
|
||||
bool ReadOnly { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 配置节的属性个数
|
||||
/// </summary>
|
||||
int Count { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取属性值(根据属性名)
|
||||
/// </summary>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
ISettingValue this[string propertyName] { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取属性值(根据属性索引)
|
||||
/// </summary>
|
||||
/// <param name="propertyIndex">属性索引</param>
|
||||
ISettingValue this[int propertyIndex] { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取某属性值
|
||||
/// </summary>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
/// <returns>属性值</returns>
|
||||
string TryGetPropertyValue(string propertyName);
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取某属性值并转换成指定类型
|
||||
/// </summary>
|
||||
/// <typeparam name="T">转换成指定的类型</typeparam>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
/// <returns>指定类型的实例</returns>
|
||||
T TryGetPropertyValue<T>(string propertyName);
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取某属性值并转换成指定类型
|
||||
/// </summary>
|
||||
/// <typeparam name="T">转换成指定的类型</typeparam>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
/// <param name="defaultValue">缺省值</param>
|
||||
/// <returns>指定类型的实例</returns>
|
||||
T TryGetPropertyValue<T>(string propertyName, T defaultValue);
|
||||
|
||||
/// <summary>
|
||||
/// 克隆属性
|
||||
/// </summary>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <param name="deep">是否深度复制</param>
|
||||
/// <returns>ISettingProperty</returns>
|
||||
ISettingProperty Clone(bool @readonly, bool deep);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using Lskj.DevFx.Utils;
|
||||
|
||||
namespace Lskj.DevFx.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置值接口
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 形如下面的XML节表示一个配置节:
|
||||
/// <code>
|
||||
/// <app my="myProperty">myValue</app>
|
||||
/// </code>
|
||||
/// 此时,<c>Name="app"</c>,Value的值为"myValue",Property的值为"myProperty"
|
||||
/// </remarks>
|
||||
public interface ISettingValue : ICloneable, IConverting
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前配置值是否只读
|
||||
/// </summary>
|
||||
bool ReadOnly { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 配置值名
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 配置值
|
||||
/// </summary>
|
||||
string Value { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 克隆配置值
|
||||
/// </summary>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <returns>ISettingValue</returns>
|
||||
ISettingValue Clone(bool @readonly);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using Lskj.DevFx.Utils;
|
||||
|
||||
namespace Lskj.DevFx.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置节属性的实现
|
||||
/// </summary>
|
||||
public abstract class SettingProperty : ISettingProperty
|
||||
{
|
||||
/// <summary>
|
||||
/// 保护构造方法
|
||||
/// </summary>
|
||||
/// <param name="properties">属性集合</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
protected SettingProperty(SettingValueCollection properties, bool @readonly) {
|
||||
this.properties = properties;
|
||||
this.@readonly = @readonly;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否只读
|
||||
/// </summary>
|
||||
protected bool @readonly;
|
||||
|
||||
/// <summary>
|
||||
/// 属性集合
|
||||
/// </summary>
|
||||
protected SettingValueCollection properties;
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置属性实例
|
||||
/// </summary>
|
||||
/// <param name="properties">属性集合</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <returns>SettingProperty</returns>
|
||||
protected abstract SettingProperty CreateSettingProperty(SettingValueCollection properties, bool @readonly);
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置属性实例
|
||||
/// </summary>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <returns>SettingProperty</returns>
|
||||
protected virtual SettingProperty CreateSettingProperty(bool @readonly) {
|
||||
return this.CreateSettingProperty(new SettingValueCollection(), @readonly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置值
|
||||
/// </summary>
|
||||
/// <param name="name">配置值名</param>
|
||||
/// <param name="value">配置值</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <returns>SettingValue</returns>
|
||||
protected abstract SettingValue CreateSettingValue(string name, string value, bool @readonly);
|
||||
|
||||
/// <summary>
|
||||
/// 当前配置节属性是否只读
|
||||
/// </summary>
|
||||
public virtual bool ReadOnly {
|
||||
get { return this.@readonly; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置节的属性个数
|
||||
/// </summary>
|
||||
public virtual int Count {
|
||||
get { return this.properties.Count; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取/设置属性值(根据属性名)
|
||||
/// </summary>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
public virtual SettingValue this[string propertyName] {
|
||||
get { return this.properties[propertyName]; }
|
||||
set {
|
||||
if(this.ReadOnly) {
|
||||
throw new ConfigException("配置属性只读");
|
||||
}
|
||||
this.properties.Set(propertyName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取属性值(根据属性索引)
|
||||
/// </summary>
|
||||
/// <param name="propertyIndex">属性索引</param>
|
||||
public virtual SettingValue this[int propertyIndex] {
|
||||
get { return this.properties[propertyIndex]; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取某属性值
|
||||
/// </summary>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
/// <returns>属性值</returns>
|
||||
public virtual string TryGetPropertyValue(string propertyName) {
|
||||
SettingValue value = this.properties[propertyName];
|
||||
if (value != null) {
|
||||
return value.Value;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取某属性值并转换成指定类型
|
||||
/// </summary>
|
||||
/// <typeparam name="T">转换成指定的类型</typeparam>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
/// <returns>指定类型的实例</returns>
|
||||
public virtual T TryGetPropertyValue<T>(string propertyName) {
|
||||
return this.TryGetPropertyValue<T>(propertyName, default(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取某属性值并转换成指定类型
|
||||
/// </summary>
|
||||
/// <typeparam name="T">转换成指定的类型</typeparam>
|
||||
/// <param name="propertyName">属性名</param>
|
||||
/// <param name="defaultValue">缺省值</param>
|
||||
/// <returns>指定类型的实例</returns>
|
||||
public virtual T TryGetPropertyValue<T>(string propertyName, T defaultValue) {
|
||||
SettingValue value = this.properties[propertyName];
|
||||
if (value != null) {
|
||||
return (value as IConverting).TryToObject<T>(defaultValue);
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual SettingProperty Merge(SettingProperty property) {
|
||||
foreach(string key in property.properties.Keys) {
|
||||
switch(key) {
|
||||
case ConfigSetting.ConfigFilePropertyName:
|
||||
case ConfigSetting.ConfigNodePropertyName:
|
||||
break;
|
||||
default:
|
||||
this.properties.Set(property[key].Clone());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
#region Clone
|
||||
|
||||
/// <summary>
|
||||
/// 克隆配置属性
|
||||
/// </summary>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <param name="deep">是否深度复制</param>
|
||||
/// <returns>SettingProperty</returns>
|
||||
public virtual SettingProperty Clone(bool @readonly, bool deep) {
|
||||
SettingProperty property = this.CreateSettingProperty(@readonly);
|
||||
if(deep) {
|
||||
foreach(SettingValue settingValue in this.properties.Values) {
|
||||
property.properties.Add(settingValue.Clone(@readonly));
|
||||
}
|
||||
} else {
|
||||
property.properties = this.properties;
|
||||
}
|
||||
return property;
|
||||
}
|
||||
|
||||
#endregion Clone
|
||||
|
||||
#region ICloneable Members
|
||||
|
||||
object ICloneable.Clone() {
|
||||
return this.Clone(this.ReadOnly, true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ISettingProperty Members
|
||||
|
||||
bool ISettingProperty.ReadOnly {
|
||||
get { return this.ReadOnly; }
|
||||
}
|
||||
|
||||
int ISettingProperty.Count {
|
||||
get { return this.Count; }
|
||||
}
|
||||
|
||||
ISettingValue ISettingProperty.this[string propertyName] {
|
||||
get { return this[propertyName]; }
|
||||
}
|
||||
|
||||
ISettingValue ISettingProperty.this[int propertyIndex] {
|
||||
get { return this[propertyIndex]; }
|
||||
}
|
||||
|
||||
ISettingProperty ISettingProperty.Clone(bool @readonly, bool deep) {
|
||||
return this.Clone(@readonly, deep);
|
||||
}
|
||||
|
||||
string ISettingProperty.TryGetPropertyValue(string propertyName) {
|
||||
return this.TryGetPropertyValue(propertyName);
|
||||
}
|
||||
|
||||
T ISettingProperty.TryGetPropertyValue<T>(string propertyName) {
|
||||
return this.TryGetPropertyValue<T>(propertyName);
|
||||
}
|
||||
|
||||
T ISettingProperty.TryGetPropertyValue<T>(string propertyName, T defaultValue) {
|
||||
return this.TryGetPropertyValue<T>(propertyName, defaultValue);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using Lskj.DevFx.Utils;
|
||||
|
||||
namespace Lskj.DevFx.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置值的实现,提供一些缺省的实现
|
||||
/// </summary>
|
||||
public abstract class SettingValue : Converting, ISettingValue
|
||||
{
|
||||
/// <summary>
|
||||
/// 保护构造方法
|
||||
/// </summary>
|
||||
/// <param name="name">配置值名</param>
|
||||
/// <param name="value">配置值</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
protected SettingValue(string name, string value, bool @readonly) {
|
||||
this.name = name;
|
||||
this.value = @value;
|
||||
this.@readonly = @readonly;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置值名
|
||||
/// </summary>
|
||||
protected string name;
|
||||
/// <summary>
|
||||
/// 配置值
|
||||
/// </summary>
|
||||
protected string value;
|
||||
/// <summary>
|
||||
/// 是否只读
|
||||
/// </summary>
|
||||
protected bool @readonly;
|
||||
|
||||
/// <summary>
|
||||
/// 被转换的值
|
||||
/// </summary>
|
||||
protected override string ConvertingValue {
|
||||
get { return this.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置值实例
|
||||
/// </summary>
|
||||
/// <param name="name">配置值名</param>
|
||||
/// <param name="value">配置值</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <returns>SettingValue</returns>
|
||||
protected abstract SettingValue CreateSettingValue(string name, string value, bool @readonly);
|
||||
|
||||
/// <summary>
|
||||
/// 配置值名
|
||||
/// </summary>
|
||||
public virtual string Name {
|
||||
get { return this.name; }
|
||||
set {
|
||||
if(this.ReadOnly) {
|
||||
throw new ConfigException("配置值只读");
|
||||
} else {
|
||||
this.name = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置值
|
||||
/// </summary>
|
||||
public virtual string Value {
|
||||
get { return this.value; }
|
||||
set {
|
||||
if (this.ReadOnly) {
|
||||
throw new ConfigException("配置值只读");
|
||||
} else {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前配置值是否只读
|
||||
/// </summary>
|
||||
public virtual bool ReadOnly {
|
||||
get { return this.@readonly; }
|
||||
}
|
||||
|
||||
internal virtual void SetName(string name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
#region Clone
|
||||
|
||||
/// <summary>
|
||||
/// 克隆配置值
|
||||
/// </summary>
|
||||
/// <returns>SettingValue</returns>
|
||||
public virtual SettingValue Clone() {
|
||||
return this.Clone(this.ReadOnly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 克隆配置值
|
||||
/// </summary>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <returns>SettingValue</returns>
|
||||
public virtual SettingValue Clone(bool @readonly) {
|
||||
return this.CreateSettingValue(this.Name, this.Value, @readonly);
|
||||
}
|
||||
|
||||
#endregion Clone
|
||||
|
||||
#region ICloneable Members
|
||||
|
||||
object ICloneable.Clone() {
|
||||
return this.Clone();
|
||||
}
|
||||
|
||||
ISettingValue ISettingValue.Clone(bool @readonly) {
|
||||
return this.Clone();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ISettingValue Members
|
||||
|
||||
bool ISettingValue.ReadOnly {
|
||||
get { return this.ReadOnly; }
|
||||
}
|
||||
|
||||
string ISettingValue.Name {
|
||||
get { return this.Name; }
|
||||
}
|
||||
|
||||
string ISettingValue.Value {
|
||||
get { return this.Value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using Lskj.DevFx.Utils;
|
||||
|
||||
namespace Lskj.DevFx.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置值集合
|
||||
/// </summary>
|
||||
public class SettingValueCollection : CollectionBase<SettingValue>
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造方法
|
||||
/// </summary>
|
||||
public SettingValueCollection() : base(true) {}
|
||||
|
||||
/// <summary>
|
||||
/// 添加配置值
|
||||
/// </summary>
|
||||
/// <param name="value">配置值</param>
|
||||
/// <returns>配置值</returns>
|
||||
public virtual SettingValue Add(SettingValue value) {
|
||||
this.Add(value.Name, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加/替换配置值(如果存在则替换)
|
||||
/// </summary>
|
||||
/// <param name="value">配置值</param>
|
||||
public virtual void Set(SettingValue value) {
|
||||
this.Set(value.Name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Xml;
|
||||
|
||||
namespace Lskj.DevFx.Config.XmlConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// XML方式实现配置节 <see cref="ConfigSetting"/>
|
||||
/// </summary>
|
||||
public class XmlConfigSetting : ConfigSetting
|
||||
{
|
||||
#region constructor
|
||||
|
||||
/// <summary>
|
||||
/// 构造方法
|
||||
/// </summary>
|
||||
protected XmlConfigSetting() {}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置节实例
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override ConfigSetting CreateConfigSetting() {
|
||||
return new XmlConfigSetting();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置值
|
||||
/// </summary>
|
||||
/// <param name="name">配置值名</param>
|
||||
/// <param name="value">配置值</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <returns>SettingValue</returns>
|
||||
protected override SettingValue CreateSettingValue(string name, string value, bool @readonly) {
|
||||
return new XmlSettingValue(name, value, @readonly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置属性实例
|
||||
/// </summary>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <returns>SettingProperty</returns>
|
||||
protected override SettingProperty CreateSettingProperty(bool @readonly) {
|
||||
return new XmlSettingProperty(@readonly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换成字符串
|
||||
/// </summary>
|
||||
/// <param name="sb"><see cref="StringBuilder"/></param>
|
||||
/// <param name="layerIndex">所处层次</param>
|
||||
protected override void ToString(StringBuilder sb, int layerIndex) {
|
||||
string layerString = new string('\t', layerIndex);
|
||||
sb.AppendFormat("{0}<{1}", layerString, this.SettingName);
|
||||
if(this.Property.Count > 0) {
|
||||
sb.AppendFormat(" {0}", this.Property);
|
||||
}
|
||||
if(this.childSettings.Count > 0) {
|
||||
sb.AppendFormat(">{0}\r\n", HttpUtility.HtmlAttributeEncode(this.Value.Value));
|
||||
foreach(XmlConfigSetting setting in this.childSettings.Values) {
|
||||
setting.ToString(sb, layerIndex + 1);
|
||||
}
|
||||
sb.AppendFormat("{0}</{1}>\r\n", layerString, this.SettingName);
|
||||
} else {
|
||||
if(this.Value.Value != null) {
|
||||
sb.AppendFormat(">{0}</{1}>\r\n", HttpUtility.HtmlAttributeEncode(this.Value.Value), this.SettingName);
|
||||
} else {
|
||||
sb.AppendLine(" />");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置节
|
||||
/// </summary>
|
||||
/// <param name="parent">父配置节</param>
|
||||
/// <param name="xmlNode">XML节</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <param name="searchPath">XML搜索目录列表</param>
|
||||
/// <param name="configFiles">如果有子配置文件,则添加到此列表</param>
|
||||
internal static XmlConfigSetting Create(XmlConfigSetting parent, XmlNode xmlNode, bool @readonly, string[] searchPath, List<string> configFiles) {
|
||||
if(xmlNode.NodeType != XmlNodeType.Element) {
|
||||
throw new ConfigException("解析到非法元素");
|
||||
}
|
||||
|
||||
if(searchPath == null || searchPath.Length <= 0) {
|
||||
searchPath = ConfigHelper.ConfigFileDefaultSearchPath;
|
||||
}
|
||||
XmlConfigSetting setting = new XmlConfigSetting();
|
||||
setting.parent = parent;
|
||||
setting.ReadOnly = @readonly;
|
||||
setting.property = new XmlSettingProperty(xmlNode, @readonly);
|
||||
setting.childSettings = new ConfigSettingCollection(true);
|
||||
setting.operatorSettings = new ConfigSettingCollection(false);
|
||||
setting.value = new XmlSettingValue(xmlNode, @readonly);
|
||||
setting.SettingName = setting.Name;
|
||||
ConfigSettingOperator settingOperator = setting.SettingOperator;
|
||||
if (settingOperator != 0 && settingOperator != ConfigSettingOperator.Clear) {
|
||||
string newName = setting.Property.TryGetPropertyValue(ConfigNamePropertyName);
|
||||
if(string.IsNullOrEmpty(newName)) {
|
||||
throw new ConfigException("配置命令未定义属性:" + ConfigNamePropertyName);
|
||||
}
|
||||
setting.value.SetName(newName);
|
||||
}
|
||||
|
||||
foreach(XmlNode node in xmlNode.ChildNodes) {
|
||||
if(node.NodeType != XmlNodeType.Element) {
|
||||
continue;
|
||||
}
|
||||
XmlConfigSetting childSetting = Create(setting, node, @readonly, searchPath, configFiles);
|
||||
setting.operatorSettings.Add(childSetting);
|
||||
}
|
||||
Compile(setting, setting.operatorSettings);
|
||||
|
||||
string configFile = setting.ConfigFile;
|
||||
string configNode = setting.ConfigNode;
|
||||
if(!string.IsNullOrEmpty(configFile)) {
|
||||
configFile = ConfigHelper.SearchConfigFile(configFile, searchPath);
|
||||
if(!string.IsNullOrEmpty(configFile)) {
|
||||
if(string.IsNullOrEmpty(configNode)) {
|
||||
configNode = "/";
|
||||
}
|
||||
XmlNode newNode = ConfigHelper.LoadXmlNodeFromFile(configFile, configNode, false);
|
||||
if(newNode != null) {
|
||||
if(configFiles != null) {
|
||||
configFiles.Add(configFile);
|
||||
}
|
||||
setting.Merge(Create(parent, newNode, @readonly, searchPath, configFiles));
|
||||
}
|
||||
}
|
||||
}
|
||||
return setting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置节
|
||||
/// </summary>
|
||||
/// <param name="fileName">XML文件</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <param name="searchPath">XML搜索目录列表</param>
|
||||
/// <param name="configFiles">如果有子配置文件,则添加到此列表</param>
|
||||
/// <returns>配置节</returns>
|
||||
internal static XmlConfigSetting Create(string fileName, bool @readonly, string[] searchPath, List<string> configFiles) {
|
||||
fileName = ConfigHelper.SearchConfigFile(fileName, searchPath);
|
||||
if(string.IsNullOrEmpty(fileName)) {
|
||||
return null;
|
||||
}
|
||||
XmlNode xmlNode = ConfigHelper.LoadXmlNodeFromFile(fileName, "/", false);
|
||||
if(xmlNode == null) {
|
||||
return null;
|
||||
}
|
||||
if(searchPath == null || searchPath.Length <= 0) {
|
||||
searchPath = ConfigHelper.ConfigFileDefaultSearchPath;
|
||||
}
|
||||
string[] newSearchPath = new string[searchPath.Length + 1];
|
||||
newSearchPath[0] = Path.GetDirectoryName(fileName);
|
||||
searchPath.CopyTo(newSearchPath, 1);
|
||||
return Create(null, xmlNode, @readonly, newSearchPath, configFiles);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置节
|
||||
/// </summary>
|
||||
/// <param name="fileName">XML文件</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <returns>配置节</returns>
|
||||
internal static XmlConfigSetting Create(string fileName, bool @readonly) {
|
||||
return Create(fileName, @readonly, ConfigHelper.ConfigFileDefaultSearchPath, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置节
|
||||
/// </summary>
|
||||
/// <param name="fileName">XML文件</param>
|
||||
/// <returns>配置节</returns>
|
||||
internal static XmlConfigSetting Create(string fileName) {
|
||||
return Create(fileName, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Lskj.DevFx.Config.XmlConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用XML实现配置节属性:<see cref="SettingProperty"/>
|
||||
/// </summary>
|
||||
public class XmlSettingProperty : SettingProperty
|
||||
{
|
||||
#region constructor
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
/// <param name="properties">属性集合</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
protected XmlSettingProperty(SettingValueCollection properties, bool @readonly) : base(properties, @readonly) {}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
public XmlSettingProperty(bool @readonly) : base(new SettingValueCollection(), @readonly) { }
|
||||
|
||||
/// <summary>
|
||||
/// 使用XmlNode初始化
|
||||
/// </summary>
|
||||
/// <param name="xmlNode">XmlNode</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
public XmlSettingProperty(XmlNode xmlNode, bool @readonly) : this(@readonly) {
|
||||
this.InitData(xmlNode, @readonly);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private members
|
||||
|
||||
/// <summary>
|
||||
/// 初始化XML结点
|
||||
/// </summary>
|
||||
private void InitData(XmlNode xmlNode, bool @readonly) {
|
||||
foreach(XmlNode attribute in xmlNode.Attributes) {
|
||||
string name = attribute.Name;
|
||||
string @value = attribute.Value;
|
||||
this.properties.Set(new XmlSettingValue(name, @value, @readonly));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置属性实例
|
||||
/// </summary>
|
||||
/// <param name="properties">属性集合</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <returns>SettingProperty</returns>
|
||||
protected override SettingProperty CreateSettingProperty(SettingValueCollection properties, bool @readonly) {
|
||||
return new XmlSettingProperty(properties, @readonly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置值
|
||||
/// </summary>
|
||||
/// <param name="name">配置值名</param>
|
||||
/// <param name="value">配置值</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <returns>SettingValue</returns>
|
||||
protected override SettingValue CreateSettingValue(string name, string value, bool @readonly) {
|
||||
return new XmlSettingValue(name, value, @readonly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换成字符串格式
|
||||
/// </summary>
|
||||
/// <returns>字符串</returns>
|
||||
public override string ToString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach(SettingValue value in this.properties.Values) {
|
||||
sb.AppendFormat(" {0}", value);
|
||||
}
|
||||
if(sb.Length > 0) {
|
||||
sb.Remove(0, 1);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/******************************************************************************
|
||||
Copyright 2005-2007 R2@DevFx.NET
|
||||
DevFx.NET is free software; you can redistribute it and/or modify
|
||||
it under the terms of the Lesser GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DevFx.NET is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
Lesser GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the Lesser GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/*******************************************************************************/
|
||||
|
||||
using System.Web;
|
||||
using System.Xml;
|
||||
|
||||
namespace Lskj.DevFx.Config.XmlConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用XML实现<see cref="SettingValue"/>
|
||||
/// </summary>
|
||||
public class XmlSettingValue : SettingValue
|
||||
{
|
||||
#region constructor
|
||||
|
||||
/// <summary>
|
||||
/// 使用name/value的形式初始化
|
||||
/// </summary>
|
||||
/// <param name="name">配置值名</param>
|
||||
/// <param name="value">配置值</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
public XmlSettingValue(string name, string @value, bool @readonly) : base(name, @value, @readonly) {}
|
||||
|
||||
/// <summary>
|
||||
/// 使用XmlNode初始化
|
||||
/// </summary>
|
||||
/// <param name="xmlNode">XmlNode</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
public XmlSettingValue(XmlNode xmlNode, bool @readonly) : base(null, null, @readonly) {
|
||||
this.name = xmlNode.Name;
|
||||
foreach(XmlNode node in xmlNode.ChildNodes) {
|
||||
if(node.NodeType == XmlNodeType.Text) {
|
||||
this.value = node.Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 创建配置值实例
|
||||
/// </summary>
|
||||
/// <param name="name">配置值名</param>
|
||||
/// <param name="value">配置值</param>
|
||||
/// <param name="readonly">是否只读</param>
|
||||
/// <returns>SettingValue</returns>
|
||||
protected override SettingValue CreateSettingValue(string name, string value, bool @readonly) {
|
||||
return new XmlSettingValue(name, value, @readonly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换成字符串格式
|
||||
/// </summary>
|
||||
/// <returns>字符串</returns>
|
||||
public override string ToString() {
|
||||
return string.Format("{0}=\"{1}\"", this.Name, HttpUtility.HtmlAttributeEncode(this.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Collections.Specialized;
|
||||
using System.Configuration;
|
||||
using Lskj.DevFx.Utils;
|
||||
|
||||
namespace Lskj.DevFx.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// 应用程序配置操作类
|
||||
/// </summary>
|
||||
public class XmlConfiger
|
||||
{
|
||||
private string filename = null;
|
||||
|
||||
private XmlDocument doc = null;
|
||||
|
||||
public XmlConfiger()
|
||||
{
|
||||
FileName = ApplicationHelper.GetApplicationConfigFile();
|
||||
}
|
||||
|
||||
public XmlConfiger(string fileName)
|
||||
{
|
||||
FileName = fileName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置文件路径
|
||||
/// </summary>
|
||||
public string FileName
|
||||
{
|
||||
get { return filename; }
|
||||
set
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value) && filename != value)
|
||||
{
|
||||
filename = value;
|
||||
//载入XML文档对象
|
||||
doc = LoadXmlDocument(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置文件XML文档对象
|
||||
/// </summary>
|
||||
public XmlDocument Document
|
||||
{
|
||||
get { return doc; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取配置文件中的字符型信息
|
||||
/// </summary>
|
||||
/// <param name="SectionName"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defaultvalue"></param>
|
||||
/// <returns></returns>
|
||||
public string GetString(string SectionName, string key,string defaultvalue)
|
||||
{
|
||||
if (doc == null)
|
||||
throw new ArgumentNullException("Document");
|
||||
|
||||
try
|
||||
{
|
||||
if (SectionName == null || SectionName == "")
|
||||
{
|
||||
XmlNode xNode;
|
||||
XmlElement xElem;
|
||||
xNode = doc.SelectSingleNode("//appSettings");
|
||||
xElem = (XmlElement)xNode.SelectSingleNode("//add[@key='" + key + "']");
|
||||
|
||||
if (xElem != null)
|
||||
return xElem.GetAttribute("value");
|
||||
else
|
||||
return "";
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
NameValueCollection cfgName = (NameValueCollection)ConfigurationManager.GetSection(SectionName);
|
||||
if (cfgName[key] == null || cfgName[key] == "")
|
||||
{
|
||||
return defaultvalue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return cfgName[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return defaultvalue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 得到配置文件中的配置decimal信息
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public decimal GetDecimal(string SectionName, string key,decimal defaultvalue)
|
||||
{
|
||||
decimal result = 0;
|
||||
string cfgVal = GetString(SectionName, key, defaultvalue.ToString());
|
||||
if (null != cfgVal && string.Empty != cfgVal)
|
||||
{
|
||||
result = decimal.Parse(cfgVal);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 得到配置文件中的配置int信息
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public int GetInt(string SectionName, string key, decimal defaultvalue)
|
||||
{
|
||||
int result = 0;
|
||||
string cfgVal = GetString(SectionName, key, defaultvalue.ToString());
|
||||
if (null != cfgVal && string.Empty != cfgVal)
|
||||
{
|
||||
result = Int32.Parse(cfgVal);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
/// <summary>
|
||||
/// 写入配置文件
|
||||
/// </summary>
|
||||
/// <param name="SectionName">节点名称</param>
|
||||
/// <parma name="key">键名</param>
|
||||
/// <parma name="value">键值</param>
|
||||
public void SetValue(string SectionName, string key, string value)
|
||||
{
|
||||
if (doc == null)
|
||||
throw new ArgumentNullException("Document");
|
||||
//重新取得 节点名
|
||||
string strSection = string.IsNullOrEmpty(SectionName) ? "appSettings" : SectionName;
|
||||
XmlNode node = doc.SelectSingleNode("//" + strSection);
|
||||
if (node == null)
|
||||
throw new InvalidOperationException("在应用程序配置文件中未找到对应的节点:" + strSection);
|
||||
|
||||
try
|
||||
{
|
||||
// 用 'add'元件 格式化是否包含键名
|
||||
// select the 'add' element that contains the key
|
||||
XmlElement elem = (XmlElement)node.SelectSingleNode(string.Format("//add[@key='{0}']", key));
|
||||
|
||||
if (elem != null)
|
||||
{
|
||||
//修改或添加键值
|
||||
elem.SetAttribute("value", value);
|
||||
}
|
||||
else
|
||||
{
|
||||
//如果没有发现键名则进行添加设置键名和键值
|
||||
elem = doc.CreateElement("add");
|
||||
elem.SetAttribute("key", key);
|
||||
elem.SetAttribute("value", value);
|
||||
node.AppendChild(elem);
|
||||
}
|
||||
doc.Save(filename);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
public void RemoveKey(string SectionName, string key)
|
||||
{
|
||||
if (doc == null)
|
||||
throw new ArgumentNullException("Document");
|
||||
|
||||
//重新取得 节点名
|
||||
XmlNode node = doc.SelectSingleNode("//" + SectionName);
|
||||
|
||||
try
|
||||
{
|
||||
if (node == null)
|
||||
throw new InvalidOperationException("应用程序配置文件中的节点 " + SectionName + " 不存在!");
|
||||
else
|
||||
{
|
||||
// 用 'add' 方法格式 key和value
|
||||
node.RemoveChild(node.SelectSingleNode(string.Format("//add[@key='{0}']", key)));
|
||||
doc.Save(filename);
|
||||
}
|
||||
}
|
||||
catch (NullReferenceException e)
|
||||
{
|
||||
throw new Exception(string.Format("应用程序配置文件中的键 {0} 不存在!", key), e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读入配置文件
|
||||
/// </summary>
|
||||
public static XmlDocument LoadXmlDocument(string file)
|
||||
{
|
||||
XmlDocument doc1 = null;
|
||||
try
|
||||
{
|
||||
doc1 = new XmlDocument();
|
||||
doc1.Load(file);
|
||||
return doc1;
|
||||
}
|
||||
catch (System.IO.FileNotFoundException e)
|
||||
{
|
||||
throw new Exception("无法找到应用程序配置文件!", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user