把CommunityServer的事件框架应用到当前的项目中,可以在一个方法调用中设置其前置和后置事件,从而把一个额外的业务处理外置到别的模块中进行独立处理。
1、需要定义一系列的委托,如public delegate void PSPRoleEventHandler(PRole pRole, PSEventArgs e);委托参数的定义决定以后事件的参数,这里的PSEventArgs用于表示一些通用的参数传入,例如ObjectState针对对象操作的状态。
public enum ObjectState
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
Create,
Update,
Delete,
None,
Runtime
}
public class PSEventArgs : EventArgs
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
private ObjectState _state;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public ObjectState State
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return _state; }
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public PSEventArgs(ObjectState state)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
_state = state;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public PSEventArgs() : this(ObjectState.None)
{ }
}
2、创建PSApplication类,用于统一定义一些事件,并从配置文件的模块配置加载这些事件的真实调用,以下为一下例子:
public class PSApplication
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
private members#region private members
private EventHandlerList Events = new EventHandlerList();
private static readonly object sync = new object();
private Hashtable modules = new Hashtable();
#endregion
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
Event Keys (static)#region Event Keys (static)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private static object EventPrePRoleUpdate = new object();
private static object EventPRoleUpdate = new object();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
#endregion
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
cnstr#region cnstr
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private PSApplication()
{ }
internal static PSApplication Instance()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
const string key = "PSApplication";
HttpContext context = HttpContext.Current;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
PSApplication app = context.Cache[key] as PSApplication;
if (app == null)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
lock (sync)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
app = context.Cache[key] as PSApplication;
if (app == null)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
PSConfiguration config = PSConfiguration.GetConfig();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
XmlNode node = config.GetConfigSection("Configurations/PSModules");
app = new PSApplication();
if (node != null)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
foreach (XmlNode n in node.ChildNodes)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (n.NodeType != XmlNodeType.Comment)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
switch (n.Name)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
case "clear":
app.modules.Clear();
break;
case "remove":
XmlAttribute removeNameAtt = n.Attributes["name"];
string removeName = removeNameAtt == null ? null : removeNameAtt.Value;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (!String.IsNullOrEmpty(removeName) && app.modules.ContainsKey(removeName))
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
app.modules.Remove(removeName);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
break;
case "add":
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
XmlAttribute en = n.Attributes["enabled"];
if (en != null && en.Value == "false")
continue;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
XmlAttribute nameAtt = n.Attributes["name"];
XmlAttribute typeAtt = n.Attributes["type"];
string name = nameAtt == null ? null : nameAtt.Value;
string itype = typeAtt == null ? null : typeAtt.Value;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (String.IsNullOrEmpty(name))
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//EventLogs.Warn("");
continue;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (String.IsNullOrEmpty(itype))
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//EventLogs.Warn("");
continue;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Type type = Type.GetType(itype);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (type == null)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//EventLogs.Warn("");
continue;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IPSModule mod = Activator.CreateInstance(type) as IPSModule;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (mod == null)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//EventLogs.Warn("");
continue;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
mod.Init(app, n);//注意,通过Configurations/PSModules/[Model]/add节的配置可以传递一些扩展的配置
app.modules.Add(name, mod);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
break;
}
}
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//以PSConfiguration的CacheKey为依赖项,即PSConfiguration的缓存过期,则本缓存也会过期
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
CacheDependency dep = new CacheDependency(null, new string[]
{ PSConfiguration.CacheKey });
context.Cache.Insert(key, app, dep);
}
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return app;
}
#endregion
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
PRole Events#region PRole Events
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
internal void ExecutePrePRoleUpdate(PRole pRole, ObjectState state)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
PSPRoleEventHandler handler = Events[EventPrePRoleUpdate] as PSPRoleEventHandler;
if (handler != null)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
handler(pRole, new PSEventArgs(state));
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
internal void ExecutePRoleUpdate(PRole pRole, ObjectState state)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
PSPRoleEventHandler handler = Events[EventPRoleUpdate] as PSPRoleEventHandler;
if (handler != null)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
handler(pRole, new PSEventArgs(state));
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 触发事件,在PRole数据保存到数据库之前
/// </summary>
public event PSPRoleEventHandler PrePRoleUpdate
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
add
{ Events.AddHandler(EventPrePRoleUpdate, value); }
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
remove
{ Events.RemoveHandler(EventPrePRoleUpdate, value); }
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 触发事件,在PRole数据保存到数据库之后
/// </summary>
public event PSPRoleEventHandler PRoleUpdate
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
add
{ Events.AddHandler(EventPRoleUpdate, value); }
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
remove
{ Events.RemoveHandler(EventPRoleUpdate, value); }
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
#endregion
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
其中的internal static PSApplication Instance()方法用于实例化PSApplication对象并从配置文件中加载事件真实实现的模块信息,例如模块配置可以写成这样:
<Configurations>
<PSModules>
<add name="PRoleModule" type="CSDN.PermissionService.Components.PRoleModule, CSDN.PermissionService.Components" />
</PSModules>
</Configurations>
这样通过组件CSDN.PermissionService.Components中的CSDN.PermissionService.Components.PRoleModule模块就可以加载对角色操作的一些前后事件的功能
public event PSPRoleEventHandler PrePRoleUpdate 添加或移除在PRole数据保存到数据库之前的触发事件
public event PSPRoleEventHandler PRoleUpdate 添加或移除在PRole数据保存到数据库之后的触发事件
private EventHandlerList Events = new EventHandlerList(); 用于保存一下委托的事件列表
对于模块设计需要定实现一个IPSModule接口
public interface IPSModule
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
void Init(PSApplication psa, XmlNode node);
}
例如:PRoleModule
public class PRoleModule : IPSModule
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void Init(PSApplication psa, System.Xml.XmlNode node)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
psa.PrePRoleUpdate += new PSPRoleEventHandler(psa_PrePRoleUpdate);
psa.PRoleUpdate += new PSPRoleEventHandler(psa_PRoleUpdate);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private void psa_PrePRoleUpdate(PRole pRole, PSEventArgs e)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//前置事件
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private void psa_PRoleUpdate(PRole pRole, PSEventArgs e)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//后置事件
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
在模块里可以注册一些相关的事件,并且实现这些事件,以把一些前置或后置处理外置到主业务体外。
对于PSEvents是些方法调用的封装:
public class PSEvents
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
PRoles#region PRoles
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public static void BeforePRole(PRole pRole, ObjectState state)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
PSApplication.Instance().ExecutePrePRoleUpdate(pRole, state);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public static void AfterPRole(PRole pRole, ObjectState state)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
PSApplication.Instance().ExecutePRoleUpdate(pRole, state);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
#endregion
}