您现在的位置是:首页 > cms教程 > Discuz教程Discuz教程
Discuz!NT分析Config实现方法介绍
听寒2025-07-10Discuz教程已有人查阅
导读其实很早的时候就想琢磨下Discuz!NT的一些东西,今天着重吧Discuz的有关于配置的信息研究了下,拿出来与大家共同分享下Discuz!NT在web.config自定义了httpModule
其实很早的时候就想琢磨下Discuz!NT的一些东西,今天着重吧Discuz的有关于配置的信息研究了下,拿出来与大家共同分享下Discuz!NT在web.config自定义了httpModule模块去实现了
OnlineUsers.ResetOnLineList首先将用户信息清零
这是上面的是大方向,今天就说一个地方:ScheduleConfigs.GetConfig()这句话,也就是Discuz!NT 采用的配置文件方式Discuz!NT 将配置文件大部分的放入了web底下的config 目录里了。
介绍下各个类的作用
ScheduleConfigs 是对外部公开的对象,它仅有两个功能,一是读出配置文件,二是存储配置文件信息,均无参数/ScheduleConfigInfo 是一个领域模型,对应相应配置的config,为了统一方便处理,这里实现了仅作规定约束的IConfigInfo接口,此接口没有任何内容。
实现ScheduleConfigs 中的功能主要依赖于ScheduleConfigFileManager,其中用static 存储配置信息,由于是static型的,则只需要存储一次即可供全局共享大概就是这样,后来我把Discuz!NT 的配置单独抽出来了,大概是这样的样子的在这里我只向外部暴露DeclareDatertimeConfigs 这个类,其余的都为internal
部分代码如下
var config = DeclareDateTimeConfigs.GetConfig();即可得到配置信息存储配置信息也很简单DeclareDateTimeConfigs.SaveConfig(config);因为此处是static 所以可以不用考虑缓存的问题。
IHttpModule<httpModules>
<add type="Discuz.Forum.HttpModule, Discuz.Forum" name="HttpModule" />
</httpModules>这样的话,在程序启动的时候,则首先执行此处的HttpModule里的Init方法
public void Init(HttpApplication context)
{
OnlineUsers.ResetOnlineList();
context.BeginRequest += new EventHandler(ReUrl_BeginRequest);
if (eventTimer == null && ScheduleConfigs.GetConfig().Enabled)
{
EventLogs.LogFileName = Utils.GetMapPath(string.Format("{0}cache/scheduleeventfaildlog.config",
BaseConfigs.GetForumPath));
EventManager.RootPath = Utils.GetMapPath(BaseConfigs.GetForumPath);
eventTimer = new Timer(new TimerCallback(ScheduledEventWorkCallback), context.Context,
60000, EventManager.TimerMinutesInterval * 60000);
}
context.Error += new EventHandler(Application_OnError);
}
一行一行的讲解:OnlineUsers.ResetOnLineList首先将用户信息清零
context.BeginRequest += new EventHandler(ReUrl_BeginRequest)
这行代码指定地址请求处理的方法(ReUrl_BeginRequest这个方法是处理URL 地址的)
if(eventTimer == null && ScheduleConfigs.GetConfig().Enabled)
判断是否配置开启了“计划任务”且计时器是否初始化如果开启了“计划任务”且计时器未启动,则启用计划任务信息之后context.Error += new EventHandler(Application_OnError) 为异常处理这是上面的是大方向,今天就说一个地方:ScheduleConfigs.GetConfig()这句话,也就是Discuz!NT 采用的配置文件方式Discuz!NT 将配置文件大部分的放入了web底下的config 目录里了。
介绍下各个类的作用
ScheduleConfigs 是对外部公开的对象,它仅有两个功能,一是读出配置文件,二是存储配置文件信息,均无参数/ScheduleConfigInfo 是一个领域模型,对应相应配置的config,为了统一方便处理,这里实现了仅作规定约束的IConfigInfo接口,此接口没有任何内容。
实现ScheduleConfigs 中的功能主要依赖于ScheduleConfigFileManager,其中用static 存储配置信息,由于是static型的,则只需要存储一次即可供全局共享大概就是这样,后来我把Discuz!NT 的配置单独抽出来了,大概是这样的样子的在这里我只向外部暴露DeclareDatertimeConfigs 这个类,其余的都为internal
部分代码如下
public class DeclareDateTimeConfigs
{
/// <summary>
/// 获取配置类实例
/// </summary>
/// <returns></returns>
public static DeclareDateTimeConfigInfo GetConfig()
{
return DeclareDateTimeConfigFileManager.LoadConfig();
}
/// <summary>
/// 保存配置类实例
/// </summary>
/// <returns></returns>
public static bool SaveConfig(DeclareDateTimeConfigInfo declareDateTimeConfigInfo)
{
DeclareDateTimeConfigFileManager scfm = new DeclareDateTimeConfigFileManager();
DeclareDateTimeConfigFileManager.ConfigInfo = declareDateTimeConfigInfo;
return scfm.SaveConfig();
}
}
internal class DeclareDateTimeConfigFileManager:DefaultConfigFileManager
{
private static DeclareDateTimeConfigInfo m_configinfo;
/// <summary>
/// 锁对象
/// </summary>
private static object m_lockHelper = new object();
/// <summary>
/// 文件修改时间
/// </summary>
private static DateTime m_fileoldchange;
/// <summary>
/// 初始化文件修改时间和对象实例
/// </summary>
static DeclareDateTimeConfigFileManager() {
m_fileoldchange = System.IO.File.GetLastWriteTime(ConfigFilePath);
m_configinfo = (DeclareDateTimeConfigInfo)DefaultConfigFileManager.DeserializeInfo(ConfigFilePath, typeof(DeclareDateTimeConfigInfo));
}
public new static IConfigInfo ConfigInfo
{
get { return m_configinfo; }
set { m_configinfo = (DeclareDateTimeConfigInfo)value; }
}
/// <summary>
/// 配置文件所在路径
/// </summary>
public static string filename = null;
/// <summary>
/// 获取配置文件所在路径
/// </summary>
public new static string ConfigFilePath
{
get
{
if (filename == null)
{
{
filename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config\\DeclareDateTime.config");
}
if (!File.Exists(filename))
{
throw new Exception("发生错误: 虚拟目录或网站根目录下没有正确的DNT.config文件");
}
}
return filename;
}
}
/// <summary>
/// 加载配置类
/// </summary>
/// <returns></returns>
public static DeclareDateTimeConfigInfo LoadConfig()
{
ConfigInfo = DefaultConfigFileManager.LoadConfig(ref m_fileoldchange, ConfigFilePath, ConfigInfo);
return ConfigInfo as DeclareDateTimeConfigInfo;
}
/// <summary>
/// 加载真正有效的配置类
/// </summary>
/// <returns></returns>
public static DeclareDateTimeConfigInfo LoadRealConfig()
{
ConfigInfo = DefaultConfigFileManager.LoadConfig(ref m_fileoldchange, ConfigFilePath, ConfigInfo, false);
return ConfigInfo as DeclareDateTimeConfigInfo;
}
/// <summary>
/// 保存配置
/// </summary>
/// <returns></returns>
public override bool SaveConfig()
{
return base.SaveConfig(ConfigFilePath, ConfigInfo);
}
}
internal class DefaultConfigFileManager
{
/// <summary>
/// 文件所在路径变量
/// </summary>
private static string m_configfilepath;
/// <summary>
/// 临时配置对象变量
/// </summary>
private static IConfigInfo m_configinfo = null;
/// <summary>
/// 锁对象
/// </summary>
private static object m_lockHelper = new object();
/// <summary>
/// 文件所在路径
/// </summary>
public static string ConfigFilePath
{
get { return m_configfilepath; }
set { m_configfilepath = value; }
}
/// <summary>
/// 临时配置对象
/// </summary>
public static IConfigInfo ConfigInfo
{
get { return m_configinfo; }
set { m_configinfo = value; }
}
/// <summary>
/// 加载(反序列化)指定对象类型的配置对象
/// </summary>
/// <param name="fileoldchange">文件加载时间</param>
/// <param name="configFilePath">配置文件所在路径</param>
/// <param name="configinfo">相应的变量 注:该参数主要用于设置m_configinfo变量 和 获取类型.GetType()</param>
/// <returns></returns>
protected static IConfigInfo LoadConfig(ref DateTime fileoldchange, string configFilePath, IConfigInfo configinfo)
{
return LoadConfig(ref fileoldchange, configFilePath, configinfo, true);
}
/// <summary>
/// 加载(反序列化)指定对象类型的配置对象
/// </summary>
/// <param name="fileoldchange">文件加载时间</param>
/// <param name="configFilePath">配置文件所在路径(包括文件名)</param>
/// <param name="configinfo">相应的变量 注:该参数主要用于设置m_configinfo变量 和 获取类型.GetType()</param>
/// <param name="checkTime">是否检查并更新传递进来的"文件加载时间"变量</param>
/// <returns></returns>
protected static IConfigInfo LoadConfig(ref DateTime fileoldchange, string configFilePath, IConfigInfo configinfo, bool checkTime)
{
lock (m_lockHelper)
{
m_configfilepath = configFilePath;
m_configinfo = configinfo;
if (checkTime)
{
DateTime m_filenewchange = System.IO.File.GetLastWriteTime(configFilePath);
//当程序运行中config文件发生变化时则对config重新赋值
if (fileoldchange != m_filenewchange)
{
fileoldchange = m_filenewchange;
m_configinfo = DeserializeInfo(configFilePath, configinfo.GetType());
}
}
else
m_configinfo = DeserializeInfo(configFilePath, configinfo.GetType());
return m_configinfo;
}
}
/// <summary>
/// 反序列化指定的类
/// </summary>
/// <param name="configfilepath">config 文件的路径</param>
/// <param name="configtype">相应的类型</param>
/// <returns></returns>
public static IConfigInfo DeserializeInfo(string configfilepath, Type configtype)
{
return (IConfigInfo)SerializationHelper.Load(configtype, configfilepath);
}
/// <summary>
/// 保存配置实例(虚方法需继承)
/// </summary>
/// <returns></returns>
public virtual bool SaveConfig()
{
return true;
}
/// <summary>
/// 保存(序列化)指定路径下的配置文件
/// </summary>
/// <param name="configFilePath">指定的配置文件所在的路径(包括文件名)</param>
/// <param name="configinfo">被保存(序列化)的对象</param>
/// <returns></returns>
public bool SaveConfig(string configFilePath, IConfigInfo configinfo)
{
return SerializationHelper.Save(configinfo, configFilePath);
}
}
internal class SerializationHelper
{
private SerializationHelper()
{ }
private static Dictionary<int, XmlSerializer> serializer_dict = new Dictionary<int, XmlSerializer>();
public static XmlSerializer GetSerializer(Type t)
{
int type_hash = t.GetHashCode();
if (!serializer_dict.ContainsKey(type_hash))
serializer_dict.Add(type_hash, new XmlSerializer(t));
return serializer_dict[type_hash];
}
/// <summary>
/// 反序列化
/// </summary>
/// <param name="type">对象类型</param>
/// <param name="filename">文件路径</param>
/// <returns></returns>
public static object Load(Type type, string filename)
{
FileStream fs = null;
try
{
// open the stream...
fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
XmlSerializer serializer = new XmlSerializer(type);
return serializer.Deserialize(fs);
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (fs != null)
fs.Close();
}
}
/// <summary>
/// 序列化
/// </summary>
/// <param name="obj">对象</param>
/// <param name="filename">文件路径</param>
public static bool Save(object obj, string filename)
{
bool success = false;
FileStream fs = null;
// serialize it...
try
{
fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
XmlSerializer serializer = new XmlSerializer(obj.GetType());
serializer.Serialize(fs, obj);
success = true;
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (fs != null)
fs.Close();
}
return success;
}
/// <summary>
/// xml序列化成字符串
/// </summary>
/// <param name="obj">对象</param>
/// <returns>xml字符串</returns>
public static string Serialize(object obj)
{
string returnStr = "";
XmlSerializer serializer = GetSerializer(obj.GetType());
MemoryStream ms = new MemoryStream();
XmlTextWriter xtw = null;
StreamReader sr = null;
try
{
xtw = new System.Xml.XmlTextWriter(ms, Encoding.UTF8);
xtw.Formatting = System.Xml.Formatting.Indented;
serializer.Serialize(xtw, obj);
ms.Seek(0, SeekOrigin.Begin);
sr = new StreamReader(ms);
returnStr = sr.ReadToEnd();
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (xtw != null)
xtw.Close();
if (sr != null)
sr.Close();
ms.Close();
}
return returnStr;
}
public static object DeSerialize(Type type, string s)
{
byte[] b = System.Text.Encoding.UTF8.GetBytes(s);
try
{
XmlSerializer serializer = GetSerializer(type);
return serializer.Deserialize(new MemoryStream(b));
}
catch (Exception ex)
{
throw ex;
}
}
}
使用时候非常方便,使用下列语句var config = DeclareDateTimeConfigs.GetConfig();即可得到配置信息存储配置信息也很简单DeclareDateTimeConfigs.SaveConfig(config);因为此处是static 所以可以不用考虑缓存的问题。
本文标签:
很赞哦! ()
下一篇:Discuz源码调试方法
相关教程
- discuz的config_global.php文件设置说明
- Discuz的NT配置文件类discuz.config说明
- phpcms的config配置文件
- 易优CMS插件config.php配置文件修改说明
- PbootCMS执行SQL发生错误“no such table: ay_config”怎么解决
- PbootCMS执行SQL报错no such table: ay_config的解决方法
- ecshop配置文件config怎么填
- pbootcms打开网站报错:执行SQL发生错误!错误: no such table:ay_config的解决方法
- ecshop出现shop_config错误的解决方法
- 易优插件config.php配置文件参数说明
- wordpress找不到wp config.php怎么办
图文教程
Discuz!NT聚合功能页面程序架构的方法
鉴于前一阵子所写的关于Discuz!NT文章在园子中有些朋友存在疑惑这里先做一下声明:这些关于Discuz!NT的文章不是要帮助大家把这个项目中所有的程序逻辑都解释一遭
discuz论坛安装的步骤方法教程
前期环境都做好了,就不演示如何装了。安装这个两个包这里用的是3.3下载地址:因为后缀是zip的需要用unzip解压缩:没unzip这个命令的话安装解开之后会得到三个目录
Discuz建站运营必备插件分享
Discuz界面功能完善,对开发者友好,拥有丰富的插件资源,能够高度定制属于自己风格的论坛服务。但是在拥有近四千个插件的Discuz应用中心
Discuz导航和静态化URL设置方法
规范化目录即为URL后面添加斜杠/之前用ISAPI_Rewrite在IIS中伪静态不规范化目录也不会出现链接错误(为了SEO一般是范化目录的规则为:
相关源码
-
响应式WordPress简约博客主题Alt_BlogAlt_Blog主题该模板为博客内容展示设计,采用简约现代的风格理念,打造清晰的内容呈现平台。响应式布局确保在不同设备上都能获得良好的浏览体验,帮助博主更好地展示和分享内容。查看源码 -
(自适应)简繁双语响应式服装服饰西装工装校服定制pbootcms模板本模板基于PbootCMS内核开发,为服装服饰行业量身打造,尤其适合西装定制、工装生产、校服订制等服装类企业使用。模板采用响应式布局设计,确保在手机、平板、电脑查看源码 -
帝国CMS中小学生知识点试题练习题考试源码下载基于帝国CMS后台管理系统,支持在线修改联系信息、网站参数等配置,操作流程简洁明了。专注于中小学教育领域,集成知识点总结、试题练习、考试资讯等学习资源,为师生提供全面的在线学习支持与服务。查看源码 -
帝国cms7.5模板情感文学名言名句心情文章类源码下载带手机本模板基于帝国CMS7.5开发,为情感文学类网站设计。整体风格温馨雅致,布局合理清晰,特别适合建设情书分享、文学作品展示类网站。模板采用响应式设计,能够自动适配各种终端设备。查看源码 -
(自适应)橙色家政服务清洁保洁服务pbootcms网站模板源码下载模板核心价值:基于PbootCMS内核开发的家政服务类网站模板,通过模块化设计展现服务项目、团队风采、服务案例等核心板块,突出时效预约、服务标准化展示等家政行业特性。查看源码 -
帝国cms7.2淘宝客导购自媒体博客网站模板源码本模板基于帝国CMS7.2内核深度开发,为淘宝客、商品导购类自媒体及博客网站设计。通过可视化后台管理,可快速搭建具备商品推荐、比价功能的内容平台,帮助用户实现流量高效转化。查看源码
| 分享笔记 (共有 篇笔记) |
