如果大家从官方下载2.0正式版的DLL程序集中会从里面找到discuz.config这个DLL文件。通过
reflector 反射加载这个程序集后,后从中找到一些从类名称上非常相似且有一定规律(格式)的类。
它们是: 全局配置类
GeneralConfigFileManager.cs
GeneralConfigInfo.cs
GeneralConfigs.cs
Emial配置类
EmailConfigFileManager.cs
EmailConfigInfo.cs
EmailConfigs.cs
基本配置类
BaseConfigFileManager.cs
BaseConfigInfo.cs
BaseConfigInfoCollection.cs
BaseConfigs.cs
相册配置类
AlbumConfigFileManager.cs
AlbumConfigInfo.cs
AlbumConfigs.cs
聚合配置类
AggregationConfig.cs
AggregationConfigFileManager.cs
AggregationConfigInfo.cs
空间开通配置类
SpaceActiveConfigs.cs
SpaceActiveConfigFileManager.cs
SpaceActiveConfigInfo.cs.cs
可以看到,这些类基本上是以三个一组,共六组。而这六组类中的...FileManager.cs与Defau-
ltConfigFileManager.cs的关系如下图所示:

从类图上看,DefaultConfigFileManager.cs是基类,而GeneralConfigFileManager.cs,Emai-
lConfigFileManager.cs,BaseConfigFileManager.cs,AlbumConfigFileManager.cs,Aggregatio-
nConfigFileManager.cs, SpaceActiveConfigFileManager.cs分别派生自DefaultConfigFileManager。
而DefaultConfigFileManager本身也定义了几个属性和方法以便于子类调用或重写(如SaveConfig)。
而DefaultConfigFileManager的定义如下:
1
/// <summary>
2
/// 文件配置管理基类
3
/// </summary>
4
public class DefaultConfigFileManager
5
{
6
/// <summary>
7
/// 文件所在路径变量
8
/// </summary>
9
private static string m_configfilepath;
10
11
/// <summary>
12
/// 临时配置对象变量
13
/// </summary>
14
private static IConfigInfo m_configinfo = null;
15
16
/// <summary>
17
/// 锁对象
18
/// </summary>
19
private static object m_lockHelper = new object();
20
21
22
/// <summary>
23
/// 文件所在路径
24
/// </summary>
25
public static string ConfigFilePath
26
{
27
get { return m_configfilepath; }
28
set { m_configfilepath = value; }
29
}
30
31
32
/// <summary>
33
/// 临时配置对象
34
/// </summary>
35
public static IConfigInfo ConfigInfo
36
{
37
get { return m_configinfo; }
38
set { m_configinfo = value; }
39
}
40
41
/// <summary>
42
/// 加载(反序列化)指定对象类型的配置对象
43
/// </summary>
44
/// <param name="fileoldchange">文件加载时间</param>
45
/// <param name="configFilePath">配置文件所在路径</param>
46
/// <param name="configinfo">相应的变量 注:该参数主要用于设置m_configinfo变量和获取类型.GetType()</param>
47
/// <returns></returns>
48
protected static IConfigInfo LoadConfig(ref DateTime fileoldchange, string configFilePath, IConfigInfo configinfo)
49
{
50
return LoadConfig(ref fileoldchange, configFilePath, configinfo, true);
51
}
52
53
54
/// <summary>
55
/// 加载(反序列化)指定对象类型的配置对象
56
/// </summary>
57
/// <param name="fileoldchange">文件加载时间</param>
58
/// <param name="configFilePath">配置文件所在路径(包括文件名)</param>
59
/// <param name="configinfo">相应的变量 注:该参数主要用于设置m_configinfo变量 和 获取类型.GetType()</param>
60
/// <param name="checkTime">是否检查并更新传递进来的"文件加载时间"变量</param>
61
/// <returns></returns>
62
protected static IConfigInfo LoadConfig(ref DateTime fileoldchange, string configFilePath, IConfigInfo configinfo, bool checkTime)
63
{
64
m_configfilepath = configFilePath;
65
m_configinfo = configinfo;
66
67
if (checkTime)
68
{
69
DateTime m_filenewchange = System.IO.File.GetLastWriteTime(configFilePath);
70
71
//当程序运行中config文件发生变化时则对config重新赋值
72
if (fileoldchange != m_filenewchange)
73
{
74
fileoldchange = m_filenewchange;
75
lock (m_lockHelper)
76
{
77
m_configinfo = DeserializeInfo(configFilePath, configinfo.GetType());
78
}
79
}
80
}
81
else
82
{
83
lock (m_lockHelper)
84
{
85
m_configinfo = DeserializeInfo(configFilePath, configinfo.GetType());
86
}
87
88
}
89
90
91
return m_configinfo;
92
}
93
94
95
/// <summary>
96
/// 反序列化指定的类
97
/// </summary>
98
/// <param name="configfilepath">config 文件的路径</param>
99
/// <param name="configtype">相应的类型</param>
100
/// <returns></returns>
101
public static IConfigInfo DeserializeInfo(string configfilepath, Type configtype)
102
{
103
104
IConfigInfo iconfiginfo;
105
FileStream fs = null;
106
try
107
{
108
fs = new FileStream(configfilepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
109
XmlSerializer serializer = new XmlSerializer(configtype);
110
iconfiginfo = (IConfigInfo)serializer.Deserialize(fs);
111
}
112
catch (Exception ex)
113
{
114
throw ex;
115
}
116
finally
117
{
118
if (fs != null)
119
{
120
fs.Close();
121
}
122
}
123
124
return iconfiginfo;
125
}
126
127
128
public virtual bool SaveConfig()
129
{
130
return true;
131
}
132
133
/// <summary>
134
/// 保存(序列化)指定路径下的配置文件
135
/// </summary>
136
/// <param name="configFilePath">指定的配置文件所在的路径(包括文件名)</param>
137
/// <param name="configinfo">被保存(序列化)的对象</param>
138
/// <returns></returns>
139
public bool SaveConfig(string configFilePath, IConfigInfo configinfo)
140
{
141
bool succeed = false;
142
FileStream fs = null;
143
try
144
{
145
fs = new FileStream(configFilePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
146
XmlSerializer serializer = new XmlSerializer(configinfo.GetType());
147
serializer.Serialize(fs, configinfo);
148
//成功则将会返回true
149
succeed = true;
150
}
151
catch (Exception ex)
152
{
153
throw ex;
154
}
155
finally
156
{
157
if (fs != null)
158
{
159
fs.Close();
160
}
161
}
162
163
return succeed;
164
}
165
}
166
167
如果您一直关注我们的这个产品,就会从中发现在1.0正式版时,这些类(或实现这些功能的类)
还是零星分面在discuz.forum和discuz.forumpage(2.0正式版改名为discuz.web.dll)等几个DLL文件
中。后来因为考虑软件架构和出于统一配置管理的需求,产品小组将这些类重构到了discuz.config,
从此这些类有了一个“新家”。
为了便于开发和统一接口调用,我们又创建了两个接口类,就是IConfigFileManager.cs,ICon-
figInfo.cs,它们的声明如下(相关说明见注释):
IConfigFileManager.cs
1
/// <summary>
2
/// Discuz!NT 配置管理类接口
3
/// </summary>
4
public interface IConfigFileManager
5
{
6
/// <summary>
7
/// 加载配置文件
8
/// </summary>
9
/// <returns></returns>
10
IConfigInfo LoadConfig();
11
12
13
/// <summary>
14
/// 保存配置文件
15
/// </summary>
16
/// <returns></returns>
17
bool SaveConfig();
18
}
19
20
IConfigInfo.cs
1
/// <summary>
2
/// Discuz!NT 配置信息类接口
3
/// </summary>
4
public interface IConfigInfo
5
{
6
}
7
大家可以看到,其中的 IConfigInfo接口没有任何属性和方法,是一个“空接口”,这主要是为
了提供统一的向上转型需要。当然,如果以后有需要还是会添加一些方法和属性的。
为了减少篇幅,下面只对其中的 GeneralConfig进行相应介绍,一是因为它是核心的配置类,有
关它的使用在项目中不胜枚举。另外它也是这个项目中比较标准的“宝贝”,从一开始,只要有新的
功能往往都会对这个配置类有所“关照”。下面就是通过反射后得到的代码,相关的说明见注释即可:
论坛全局配置管理类(GeneralConfigFileManager):
1
/// <summary>
2
/// 全局配置设置管理类
3
/// </summary>
4
class GeneralConfigFileManager : Discuz.Config.DefaultConfigFileManager
5
{
6
private static GeneralConfigInfo m_configinfo;
7
8
9
/// <summary>
10
/// 文件修改时间
11
/// </summary>
12
private static DateTime m_fileoldchange;
13
14
15
/// <summary>
16
/// 初始化文件修改时间和对象实例
17
/// </summary>
18
static GeneralConfigFileManager()
19
{
20
m_fileoldchange = System.IO.File.GetLastWriteTime(ConfigFilePath);
21
22
try
23
{
24
m_configinfo = (GeneralConfigInfo)DefaultConfigFileManager.DeserializeInfo(ConfigFilePath, typeof(GeneralConfigInfo));
25
}
26
catch
27
{
28
if (File.Exists(ConfigFilePath))
29
{
30
ReviseConfig();
31
m_configinfo = (GeneralConfigInfo)DefaultConfigFileManager.DeserializeInfo(ConfigFilePath, typeof(GeneralConfigInfo));
32
}
33
}
34
}
35
36
public new static IConfigInfo ConfigInfo
37
{
38
get { return m_configinfo; }
39
set { m_configinfo = (GeneralConfigInfo) value; }
40
}
41
42
/// <summary>
43
/// 配置文件所在路径
44
/// </summary>
45
public static string filename = null;
46
47
48
/// <summary>
49
/// 获取配置文件所在路径
reflector 反射加载这个程序集后,后从中找到一些从类名称上非常相似且有一定规律(格式)的类。
它们是: 全局配置类
GeneralConfigFileManager.cs
GeneralConfigInfo.cs
GeneralConfigs.cs
Emial配置类
EmailConfigFileManager.cs
EmailConfigInfo.cs
EmailConfigs.cs
基本配置类
BaseConfigFileManager.cs
BaseConfigInfo.cs
BaseConfigInfoCollection.cs
BaseConfigs.cs
相册配置类
AlbumConfigFileManager.cs
AlbumConfigInfo.cs
AlbumConfigs.cs
聚合配置类
AggregationConfig.cs
AggregationConfigFileManager.cs
AggregationConfigInfo.cs
空间开通配置类
SpaceActiveConfigs.cs
SpaceActiveConfigFileManager.cs
SpaceActiveConfigInfo.cs.cs
可以看到,这些类基本上是以三个一组,共六组。而这六组类中的...FileManager.cs与Defau-
ltConfigFileManager.cs的关系如下图所示:
从类图上看,DefaultConfigFileManager.cs是基类,而GeneralConfigFileManager.cs,Emai-
lConfigFileManager.cs,BaseConfigFileManager.cs,AlbumConfigFileManager.cs,Aggregatio-
nConfigFileManager.cs, SpaceActiveConfigFileManager.cs分别派生自DefaultConfigFileManager。
而DefaultConfigFileManager本身也定义了几个属性和方法以便于子类调用或重写(如SaveConfig)。
而DefaultConfigFileManager的定义如下:
1
/// <summary>2
/// 文件配置管理基类3
/// </summary>4
public class DefaultConfigFileManager5
{6
/// <summary>7
/// 文件所在路径变量8
/// </summary>9
private static string m_configfilepath;10

11
/// <summary>12
/// 临时配置对象变量13
/// </summary>14
private static IConfigInfo m_configinfo = null;15

16
/// <summary>17
/// 锁对象18
/// </summary>19
private static object m_lockHelper = new object();20
21

22
/// <summary>23
/// 文件所在路径24
/// </summary>25
public static string ConfigFilePath26
{27
get { return m_configfilepath; }28
set { m_configfilepath = value; }29
}30

31
32
/// <summary>33
/// 临时配置对象34
/// </summary>35
public static IConfigInfo ConfigInfo36
{37
get { return m_configinfo; }38
set { m_configinfo = value; }39
}40
41
/// <summary>42
/// 加载(反序列化)指定对象类型的配置对象43
/// </summary>44
/// <param name="fileoldchange">文件加载时间</param>45
/// <param name="configFilePath">配置文件所在路径</param>46
/// <param name="configinfo">相应的变量 注:该参数主要用于设置m_configinfo变量和获取类型.GetType()</param>47
/// <returns></returns>48
protected static IConfigInfo LoadConfig(ref DateTime fileoldchange, string configFilePath, IConfigInfo configinfo)49
{50
return LoadConfig(ref fileoldchange, configFilePath, configinfo, true);51
}52

53

54
/// <summary>55
/// 加载(反序列化)指定对象类型的配置对象56
/// </summary>57
/// <param name="fileoldchange">文件加载时间</param>58
/// <param name="configFilePath">配置文件所在路径(包括文件名)</param>59
/// <param name="configinfo">相应的变量 注:该参数主要用于设置m_configinfo变量 和 获取类型.GetType()</param>60
/// <param name="checkTime">是否检查并更新传递进来的"文件加载时间"变量</param>61
/// <returns></returns>62
protected static IConfigInfo LoadConfig(ref DateTime fileoldchange, string configFilePath, IConfigInfo configinfo, bool checkTime)63
{64
m_configfilepath = configFilePath;65
m_configinfo = configinfo;66

67
if (checkTime)68
{69
DateTime m_filenewchange = System.IO.File.GetLastWriteTime(configFilePath);70

71
//当程序运行中config文件发生变化时则对config重新赋值72
if (fileoldchange != m_filenewchange)73
{74
fileoldchange = m_filenewchange;75
lock (m_lockHelper)76
{77
m_configinfo = DeserializeInfo(configFilePath, configinfo.GetType());78
}79
}80
}81
else82
{83
lock (m_lockHelper)84
{85
m_configinfo = DeserializeInfo(configFilePath, configinfo.GetType());86
}87
88
}89
90

91
return m_configinfo;92
}93

94

95
/// <summary>96
/// 反序列化指定的类97
/// </summary>98
/// <param name="configfilepath">config 文件的路径</param>99
/// <param name="configtype">相应的类型</param>100
/// <returns></returns>101
public static IConfigInfo DeserializeInfo(string configfilepath, Type configtype)102
{103

104
IConfigInfo iconfiginfo;105
FileStream fs = null;106
try107
{108
fs = new FileStream(configfilepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);109
XmlSerializer serializer = new XmlSerializer(configtype);110
iconfiginfo = (IConfigInfo)serializer.Deserialize(fs);111
}112
catch (Exception ex)113
{114
throw ex;115
}116
finally117
{118
if (fs != null)119
{120
fs.Close();121
}122
}123

124
return iconfiginfo;125
}126

127

128
public virtual bool SaveConfig()129
{130
return true;131
}132

133
/// <summary>134
/// 保存(序列化)指定路径下的配置文件135
/// </summary>136
/// <param name="configFilePath">指定的配置文件所在的路径(包括文件名)</param>137
/// <param name="configinfo">被保存(序列化)的对象</param>138
/// <returns></returns>139
public bool SaveConfig(string configFilePath, IConfigInfo configinfo)140
{141
bool succeed = false;142
FileStream fs = null;143
try144
{145
fs = new FileStream(configFilePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);146
XmlSerializer serializer = new XmlSerializer(configinfo.GetType());147
serializer.Serialize(fs, configinfo);148
//成功则将会返回true149
succeed = true;150
}151
catch (Exception ex)152
{153
throw ex;154
}155
finally156
{157
if (fs != null)158
{159
fs.Close();160
}161
}162

163
return succeed;164
}165
}166

167

如果您一直关注我们的这个产品,就会从中发现在1.0正式版时,这些类(或实现这些功能的类)
还是零星分面在discuz.forum和discuz.forumpage(2.0正式版改名为discuz.web.dll)等几个DLL文件
中。后来因为考虑软件架构和出于统一配置管理的需求,产品小组将这些类重构到了discuz.config,
从此这些类有了一个“新家”。
为了便于开发和统一接口调用,我们又创建了两个接口类,就是IConfigFileManager.cs,ICon-
figInfo.cs,它们的声明如下(相关说明见注释):
IConfigFileManager.cs
1
/// <summary>2
/// Discuz!NT 配置管理类接口3
/// </summary>4
public interface IConfigFileManager5
{6
/// <summary>7
/// 加载配置文件8
/// </summary>9
/// <returns></returns>10
IConfigInfo LoadConfig();11

12

13
/// <summary>14
/// 保存配置文件15
/// </summary>16
/// <returns></returns>17
bool SaveConfig();18
}19

20

IConfigInfo.cs
1
/// <summary>2
/// Discuz!NT 配置信息类接口3
/// </summary>4
public interface IConfigInfo5
{6
}7

大家可以看到,其中的 IConfigInfo接口没有任何属性和方法,是一个“空接口”,这主要是为
了提供统一的向上转型需要。当然,如果以后有需要还是会添加一些方法和属性的。
为了减少篇幅,下面只对其中的 GeneralConfig进行相应介绍,一是因为它是核心的配置类,有
关它的使用在项目中不胜枚举。另外它也是这个项目中比较标准的“宝贝”,从一开始,只要有新的
功能往往都会对这个配置类有所“关照”。下面就是通过反射后得到的代码,相关的说明见注释即可:
论坛全局配置管理类(GeneralConfigFileManager):
1
/// <summary>2
/// 全局配置设置管理类3
/// </summary>4
class GeneralConfigFileManager : Discuz.Config.DefaultConfigFileManager5
{6
private static GeneralConfigInfo m_configinfo;7

8
9
/// <summary>10
/// 文件修改时间11
/// </summary>12
private static DateTime m_fileoldchange;13

14

15
/// <summary>16
/// 初始化文件修改时间和对象实例17
/// </summary>18
static GeneralConfigFileManager()19
{20
m_fileoldchange = System.IO.File.GetLastWriteTime(ConfigFilePath);21

22
try23
{24
m_configinfo = (GeneralConfigInfo)DefaultConfigFileManager.DeserializeInfo(ConfigFilePath, typeof(GeneralConfigInfo));25
}26
catch27
{28
if (File.Exists(ConfigFilePath))29
{30
ReviseConfig();31
m_configinfo = (GeneralConfigInfo)DefaultConfigFileManager.DeserializeInfo(ConfigFilePath, typeof(GeneralConfigInfo));32
}33
}34
}35

36
public new static IConfigInfo ConfigInfo37
{38
get { return m_configinfo; }39
set { m_configinfo = (GeneralConfigInfo) value; }40
}41

42
/// <summary>43
/// 配置文件所在路径44
/// </summary>45
public static string filename = null;46

47

48
/// <summary>49
/// 获取配置文件所在路径