init lserp cs 5.0

This commit is contained in:
cyf
2026-07-10 15:25:05 +08:00
commit 90f3fda86a
3799 changed files with 976868 additions and 0 deletions
@@ -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) {
}
}
}
+187
View File
@@ -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>
/// &lt;app1&gt;
/// &lt;app2&gt;
/// &lt;app3&gt;&lt;/app3&gt;
/// &lt;/app2&gt;
/// &lt;/app1&gt;
/// </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>
/// &lt;configSections&gt;
/// &lt;sectionGroup name="Lskj.devfx" type="Lskj.DevFx.Config.DotNetConfig.GroupHandler, Lskj.DevFx.BaseFx"&gt;
/// &lt;section name="mail" type="Lskj.DevFx.Utils.Mail.Config.SectionHandler, Lskj.DevFx.BaseFx" /&gt;
/// ......
/// &lt;/sectionGroup&gt;
/// &lt;/configSections&gt;
///
/// ......
///
/// &lt;Lskj.devfx&gt;
/// &lt;mail&gt;
/// &lt;smtpSetting server="" port="" userName="" password="" /&gt;
/// &lt;/mail&gt;
/// &lt;/Lskj.devfx&gt;
/// ......
/// </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>
/// &lt;app my="myProperty"&gt;myValue&lt;/app&gt;
/// </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>
/// &lt;app1&gt;
/// &lt;app2&gt;
/// &lt;app3&gt;&lt;/app3&gt;
/// &lt;/app2&gt;
/// &lt;/app1&gt;
/// </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>
/// &lt;app my="myProperty"&gt;myValue&lt;/app&gt;
/// </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>
/// &lt;app my="myProperty"&gt;myValue&lt;/app&gt;
/// </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
}
}
+157
View File
@@ -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));
}
}
}
+224
View File
@@ -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);
}
}
}
}