还有一个是提供给“通知对象”提供者的!
IAdviceProvider
///<summary>
/// 通知提供者接口
/// 实现此接口的对象必须包含无参的构造函数
/// 否则将无效
/// 以下所有设置的方法名必须是非static方法的方法名称
///</summary>
public interface IAdviceProvider { ///<summary>
/// 前通知集合,其中key为要进行前通知的方法名,value为进行前通知时的处理对象
///</summary>
Dictionary<string, IBeforeAdvice> BeforeAdvices { get; }
///<summary>
/// 拦截通知集合,其中key为要拦截方法名,value为进行拦截时的处理对象
///</summary>
Dictionary<string, IStopAdvice> StopAdvices { get; }
///<summary>
/// 后通知集合,其中key为要进行后通知的方法名,value为进行后通知时的处理对象
///</summary>
Dictionary<string, IAfterAdvice> AfterAdvices { get; }
} //////////////////////////////////////////////////////////////////////////
/**示例
/// <summary>
/// 日志通知提供对象
/// </summary>
class LoggerProvider:IAdviceProvider
{ private Dictionary<string, IBeforeAdvice> beforeAdvices = new Dictionary<string, IBeforeAdvice>();
/// 通知提供者接口
/// 实现此接口的对象必须包含无参的构造函数
/// 否则将无效
/// 以下所有设置的方法名必须是非static方法的方法名称
///</summary>
public interface IAdviceProvider { ///<summary>
/// 前通知集合,其中key为要进行前通知的方法名,value为进行前通知时的处理对象
///</summary>
Dictionary<string, IBeforeAdvice> BeforeAdvices { get; }
///<summary>
/// 拦截通知集合,其中key为要拦截方法名,value为进行拦截时的处理对象
///</summary>
Dictionary<string, IStopAdvice> StopAdvices { get; }
///<summary>
/// 后通知集合,其中key为要进行后通知的方法名,value为进行后通知时的处理对象
///</summary>
Dictionary<string, IAfterAdvice> AfterAdvices { get; }
} //////////////////////////////////////////////////////////////////////////
/**示例
/// <summary>
/// 日志通知提供对象
/// </summary>
class LoggerProvider:IAdviceProvider
{ private Dictionary<string, IBeforeAdvice> beforeAdvices = new Dictionary<string, IBeforeAdvice>();
private Dictionary<string, IAfterAdvice> afterAdvices = new Dictionary<string, IAfterAdvice>();
/// <summary>
/// 必须包含无参构造函数
/// </summary>
public LoggerProvider()
{ LoggerAdvice la = new LoggerAdvice();
//将SetCurrectUser作为前通知方法
/// <summary>
/// 必须包含无参构造函数
/// </summary>
public LoggerProvider()
{ LoggerAdvice la = new LoggerAdvice();
//将SetCurrectUser作为前通知方法
beforeAdvices.Add("SetCurrectUser", la);
//将Logout作为后通知方法
//将Logout作为后通知方法
afterAdvices.Add("Logout", la); }
/// <summary>
/// 前通知集合
/// </summary>
public Dictionary<string, IBeforeAdvice> BeforeAdvices
{ get { return beforeAdvices; }
}
/// <summary>
/// 拦截通知集合,与日志无关,不返回任何信息
/// </summary>
public Dictionary<string, IStopAdvice> StopAdvices
{ get { return null; }
}
/// <summary>
/// 后通知集合
/// </summary>
public Dictionary<string, IAfterAdvice> AfterAdvices
{ get { return afterAdvices; }
}
}*/ //////////////////////////////////////////////////////////////////////////
/// <summary>
/// 前通知集合
/// </summary>
public Dictionary<string, IBeforeAdvice> BeforeAdvices
{ get { return beforeAdvices; }
}
/// <summary>
/// 拦截通知集合,与日志无关,不返回任何信息
/// </summary>
public Dictionary<string, IStopAdvice> StopAdvices
{ get { return null; }
}
/// <summary>
/// 后通知集合
/// </summary>
public Dictionary<string, IAfterAdvice> AfterAdvices
{ get { return afterAdvices; }
}
}*/ //////////////////////////////////////////////////////////////////////////
当然这个AOP的主要部分不是这个!
来看最核心的AspectOrientedProperty和Aspect
AspectOrientedProperty
///<summary>
/// 面向切面属性
/// 此属性只可以内部使用
/// 主要职责在于分配侦听接收器
/// 以及实例化切面处理对象
///</summary>
internal sealed class AspectOrientedProperty : IContextProperty, IDisposable, IContributeServerContextSink {
///<summary>
/// 通知提供者对象所在的程序集
///</summary>
private string assemblyName;
///<summary>
/// 通知提供者的对象类型全名
///</summary>
private string className;
///<summary>
/// 构造函数
///</summary>
///<param name="assemblyName">程序集</param>
///<param name="className">对象类型全名</param>
internal AspectOrientedProperty(string assemblyName, string className)
/// 面向切面属性
/// 此属性只可以内部使用
/// 主要职责在于分配侦听接收器
/// 以及实例化切面处理对象
///</summary>
internal sealed class AspectOrientedProperty : IContextProperty, IDisposable, IContributeServerContextSink {
///<summary>
/// 通知提供者对象所在的程序集
///</summary>
private string assemblyName;
///<summary>
/// 通知提供者的对象类型全名
///</summary>
private string className;
///<summary>
/// 构造函数
///</summary>
///<param name="assemblyName">程序集</param>
///<param name="className">对象类型全名</param>
internal AspectOrientedProperty(string assemblyName, string className)
{ this.assemblyName = assemblyName;
this.className = className; }
///<summary>
/// 不解释
///</summary>
public void Dispose()
{ assemblyName = null;
this.className = className; }
///<summary>
/// 不解释
///</summary>
public void Dispose()
{ assemblyName = null;
className = null;
GC.SuppressFinalize(this);
}
///<summary>
/// 当上下文冻结时调用
/// 不需要,不做实现
///</summary>
///<param name="newContext">要冻结的上下文</param>
public void Freeze(Context newContext){}
///<summary>
/// 返回一个指示上下文属性是否与新上下文兼容的布尔值。
///</summary>
///<param name="newCtx">新上下文</param>
///<returns>如果该上下文属性可以与给定的上下文中的其他上下文属性共存,则为 true;否则为 false。此处给true</returns>
public bool IsNewContextOK(Context newCtx)
{
return true;
}
///<summary>
/// 获取将属性添加到上下文中时使用的属性名称
/// 就叫Earthworm吧
///</summary>
public string Name
{
get
{
return "Earthworm"; }
}
///<summary>
/// 将第一个接收器放入到目前为止组成的接收器链中,然后将其消息接收器连接到已经形成的链前面
///</summary>
///<param name="nextSink">到目前为止组成的接收链</param>
///<returns>复合接收器链</returns>
}
///<summary>
/// 当上下文冻结时调用
/// 不需要,不做实现
///</summary>
///<param name="newContext">要冻结的上下文</param>
public void Freeze(Context newContext){}
///<summary>
/// 返回一个指示上下文属性是否与新上下文兼容的布尔值。
///</summary>
///<param name="newCtx">新上下文</param>
///<returns>如果该上下文属性可以与给定的上下文中的其他上下文属性共存,则为 true;否则为 false。此处给true</returns>
public bool IsNewContextOK(Context newCtx)
{
return true;
}
///<summary>
/// 获取将属性添加到上下文中时使用的属性名称
/// 就叫Earthworm吧
///</summary>
public string Name
{
get
{
return "Earthworm"; }
}
///<summary>
/// 将第一个接收器放入到目前为止组成的接收器链中,然后将其消息接收器连接到已经形成的链前面
///</summary>
///<param name="nextSink">到目前为止组成的接收链</param>
///<returns>复合接收器链</returns>
public IMessageSink GetServerContextSink(IMessageSink nextSink)
{ return new Aspect(nextSink,assemblyName,className);
}
}
{ return new Aspect(nextSink,assemblyName,className);
}
}
Aspect
///<summary>
/// 方面管理器
///</summary>
internal class Aspect : IMessageSink,IDisposable {
///<summary>
/// 消息槽
///</summary>
private IMessageSink sink;
///<summary>
/// 构造函数
///</summary>
///<param name="sink">消息槽</param>
///<param name="assemblyName">处理切面对象的程序集</param>
///<param name="className">处理切面对象的全名</param>
internal Aspect(IMessageSink sink, string assemblyName, string className)
/// 方面管理器
///</summary>
internal class Aspect : IMessageSink,IDisposable {
///<summary>
/// 消息槽
///</summary>
private IMessageSink sink;
///<summary>
/// 构造函数
///</summary>
///<param name="sink">消息槽</param>
///<param name="assemblyName">处理切面对象的程序集</param>
///<param name="className">处理切面对象的全名</param>
internal Aspect(IMessageSink sink, string assemblyName, string className)
{ this.sink = sink;
IAdviceProvider provider = null;
try
{ provider = Assembly.LoadFrom(assemblyName).CreateInstance(className) as IAdviceProvider;
beforeAdvices=provider.BeforeAdvices;
stopAdvices=provider.StopAdvices;
afterAdvices=provider.AfterAdvices; }
catch{}
}
///<summary>
/// 异步处理给定的消息,太麻烦,没做
///</summary>
///<param name="msg">要处理的消息</param>
///<param name="replySink">答复消息的答复接收器</param>
///<returns>提供一种在调度异步消息之后控制这些消息的方法的对象</returns>
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{ provider = Assembly.LoadFrom(assemblyName).CreateInstance(className) as IAdviceProvider;
beforeAdvices=provider.BeforeAdvices;
stopAdvices=provider.StopAdvices;
afterAdvices=provider.AfterAdvices; }
catch{}
}
///<summary>
/// 异步处理给定的消息,太麻烦,没做
///</summary>
///<param name="msg">要处理的消息</param>
///<param name="replySink">答复消息的答复接收器</param>
///<returns>提供一种在调度异步消息之后控制这些消息的方法的对象</returns>
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{
return null;
}
///<summary>
/// 获取接收器链中的下一个消息接收器
///</summary>
public IMessageSink NextSink
return null;
}
///<summary>
/// 获取接收器链中的下一个消息接收器
///</summary>
public IMessageSink NextSink
{ get
{
return sink;
{
return sink;
}
}
///<summary>
/// 同步处理给定的消息
///</summary>
///<param name="msg">要处理的消息</param>
///<returns>响应请求的答复消息</returns>
}
///<summary>
/// 同步处理给定的消息
///</summary>
///<param name="msg">要处理的消息</param>
///<returns>响应请求的答复消息</returns>
public IMessage SyncProcessMessage(IMessage msg)
{ IMethodCallMessage call = msg as IMethodCallMessage;
string methodName = call.MethodName;
IBeforeAdvice before = FindAdvice(methodName, beforeAdvices);
if (before != null)
{ IMethodCallMessage call = msg as IMethodCallMessage;
string methodName = call.MethodName;
IBeforeAdvice before = FindAdvice(methodName, beforeAdvices);
if (before != null)
{
before.DoAdvice(call);
}
IStopAdvice stop = FindAdvice(methodName, stopAdvices);
IMessage retMsg = null;
if (stop != null)
{ if (stop.CanContinueMethod(call))
{ retMsg = NextSink.SyncProcessMessage(msg);
}
}
else
{ retMsg = NextSink.SyncProcessMessage(msg); }
if (retMsg!=null)
{ IMethodReturnMessage reply = retMsg as IMethodReturnMessage;
before.DoAdvice(call);
}
IStopAdvice stop = FindAdvice(methodName, stopAdvices);
IMessage retMsg = null;
if (stop != null)
{ if (stop.CanContinueMethod(call))
{ retMsg = NextSink.SyncProcessMessage(msg);
}
}
else
{ retMsg = NextSink.SyncProcessMessage(msg); }
if (retMsg!=null)
{ IMethodReturnMessage reply = retMsg as IMethodReturnMessage;
IAfterAdvice after = FindAdvice(methodName, afterAdvices);
if (after != null)
if (after != null)
{ after.DoAdvice(reply);
}
return retMsg;
}
return new ReturnMessage(null, call);
}
///<summary>
/// 前通知集合
///</summary>
private Dictionary<string, IBeforeAdvice> beforeAdvices ;
///<summary>
/// 拦截通知集合
///</summary>
private Dictionary<string, IStopAdvice> stopAdvices ;
///<summary>
/// 后通知集合
///</summary>
private Dictionary<string, IAfterAdvice> afterAdvices;
///<summary>
/// 在通知集合中找到方法名name的通知
///</summary>
///<typeparam name="T">泛型</typeparam>
///<param name="name">方法名</param>
///<param name="advices">通知集合</param>
///<returns>泛型对象</returns>
private T FindAdvice<T>(string name, Dictionary<string, T> advices)
}
return retMsg;
}
return new ReturnMessage(null, call);
}
///<summary>
/// 前通知集合
///</summary>
private Dictionary<string, IBeforeAdvice> beforeAdvices ;
///<summary>
/// 拦截通知集合
///</summary>
private Dictionary<string, IStopAdvice> stopAdvices ;
///<summary>
/// 后通知集合
///</summary>
private Dictionary<string, IAfterAdvice> afterAdvices;
///<summary>
/// 在通知集合中找到方法名name的通知
///</summary>
///<typeparam name="T">泛型</typeparam>
///<param name="name">方法名</param>
///<param name="advices">通知集合</param>
///<returns>泛型对象</returns>
private T FindAdvice<T>(string name, Dictionary<string, T> advices)
{ T ret = default(T);
if (advices==null)
if (advices==null)
{ return ret;
}
}
lock (advices)
{ if (advices.ContainsKey(name))
{ return advices[name];
}
{ return advices[name];
}
}
return ret;
return ret;
}
///<summary>
/// 囧囧囧囧囧囧囧囧囧
///</summary>
public void Dispose()
{ sink = null;
///<summary>
/// 囧囧囧囧囧囧囧囧囧
///</summary>
public void Dispose()
{ sink = null;
GC.SuppressFinalize(this);
}
}
}
}
最后是浮云般的AspectOrientedObject
///<summary>
/// 做个假哦
///</summary>
public abstract class AspectOrientedObject:ContextBoundObject
/// 做个假哦
///</summary>
public abstract class AspectOrientedObject:ContextBoundObject
{
}
}
还有AspectOrientedAttribute
///<summary>
/// 面向切面属性
/// 用来配置处理切面的对象
///</summary>
[AttributeUsage(AttributeTargets.Class)]
/// 面向切面属性
/// 用来配置处理切面的对象
///</summary>
[AttributeUsage(AttributeTargets.Class)]
public sealed class AspectOrientedAttribute:Attribute,IContextAttribute,IDisposable
{
///<summary>
/// 处理切面对象的程序集
///</summary>
private string assemblyName;
///<summary>
/// 处理切面对象的全名
///</summary>
private string className;
///<summary>
/// 构造函数
///</summary>
///<param name="assemblyName">处理切面对象的程序集</param>
///<param name="className">处理切面对象的全名</param>
public AspectOrientedAttribute(string assemblyName, string className)
{
///<summary>
/// 处理切面对象的程序集
///</summary>
private string assemblyName;
///<summary>
/// 处理切面对象的全名
///</summary>
private string className;
///<summary>
/// 构造函数
///</summary>
///<param name="assemblyName">处理切面对象的程序集</param>
///<param name="className">处理切面对象的全名</param>
public AspectOrientedAttribute(string assemblyName, string className)
{ this.assemblyName=assemblyName;
this.className = className;
}
///<summary>
/// 囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧
///</summary>
public void Dispose()
{ assemblyName = null;
className = null;
GC.SuppressFinalize(this);
}
///<summary>
/// 在给定消息中将上下文属性返回给调用方
///</summary>
///<param name="msg">将上下文属性添加到的 消息</param>
public void GetPropertiesForNewContext(IConstructionCallMessage msg)
this.className = className;
}
///<summary>
/// 囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧
///</summary>
public void Dispose()
{ assemblyName = null;
className = null;
GC.SuppressFinalize(this);
}
///<summary>
/// 在给定消息中将上下文属性返回给调用方
///</summary>
///<param name="msg">将上下文属性添加到的 消息</param>
public void GetPropertiesForNewContext(IConstructionCallMessage msg)
{
msg.ContextProperties.Add(new AspectOrientedProperty(assemblyName,className));
}
///<summary>
/// 返回一个布尔值,指示指定上下文是否满足上下文属性的要求
///</summary>
///<param name="ctx">当前上下文属性检查所依据的上下文</param>
///<param name="msg">构造调用,需要依据当前上下文检查其参数</param>
///<returns>如果传入的上下文一切正常,则为 true;否则为 false。给false</returns>
public bool IsContextOK(Context ctx,IConstructionCallMessage msg)
msg.ContextProperties.Add(new AspectOrientedProperty(assemblyName,className));
}
///<summary>
/// 返回一个布尔值,指示指定上下文是否满足上下文属性的要求
///</summary>
///<param name="ctx">当前上下文属性检查所依据的上下文</param>
///<param name="msg">构造调用,需要依据当前上下文检查其参数</param>
///<returns>如果传入的上下文一切正常,则为 true;否则为 false。给false</returns>
public bool IsContextOK(Context ctx,IConstructionCallMessage msg)
{ return false;
}
}
}
}