- ·上一篇文章:IE中自定义右击链接打开程序
- ·下一篇文章:27个Asp.Net经常会用到的函数集
用代理技术实现简单的AOP框架
在许多的实现AOP框架的技术中,不管是静态织入还是动态织入,关键点在于拦截方法,并在方法中加入预处理和后处理。而实现方法的拦截的一个简单办法就是把类的实例委托给类的真实代理(RealProxy).这样以来,方法的调用都会被转换成消息(IMessage),同时该消息作为参数被送到真实代理的 Invoke方法。所以我们相应地改写Invoke方法,加入预处理和后处理也就OK了。
根据这个思路,可以给出一个简单的代码实现:
一,定义方法拦截的接口
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting.Messaging;
namespace LYG.Share.Interface
{
public interface IInterceptor
{
void PreProcess(IMessage requestMSG);
void PostProcess(IMessage requestMSG, IMessage returnMSG);
}
}
二,真实代理的实现
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Services;
using LYG.Share .Interface ;
namespace LYG.Share.AOP.Proxies
{
public abstract class AspectProxy : RealProxy, IInterceptor
{
private MarshalByRefObject _target = null;
public AspectProxy()
: base()
{
}
public AspectProxy(Type serverType)
: base(serverType)
{
}
public void InitProxyTarget(MarshalByRefObject target)
{
this._target = target;
}
public override IMessage Invoke(IMessage msg)
{
bool useInterception = false;
IMethodCallMessage invoke = (IMethodCallMessage)msg;
foreach (InterceptionAttribute attr in invoke.MethodBase.GetCustomAttributes(false))
{
if (attr != null)
{
if (attr.UseInterception)
{
useInterception = true;
break;
}
}
}
if (useInterception)
{
this.PreProcess(msg);
}
IConstructionCallMessage ctorInvoke = invoke as IConstructionCallMessage;
if (ctorInvoke != null)
{
RealProxy default_proxy = RemotingServices.GetRealProxy(this._target );
default_proxy.InitializeServerObject(ctorInvoke);
MarshalByRefObject tp = (MarshalByRefObject)this.GetTransparentProxy();
return EnterpriseServicesHelper.CreateConstructionReturnMessage(ctorInvoke, tp);
}
IMethodReturnMessage returnMSG = RemotingServices.ExecuteMessage(this._target, invoke);
if (useInterception)
{
this.PostProcess(msg, returnMSG);
}
return returnMSG;
}
#region implemente IInterceptor
public abstract void PreProcess(IMessage requestMSG);
public abstract void PostProcess(IMessage requestMSG, IMessage returnMSG);
#endregion
}
}
根据这个思路,可以给出一个简单的代码实现:
一,定义方法拦截的接口
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting.Messaging;
namespace LYG.Share.Interface
{
public interface IInterceptor
{
void PreProcess(IMessage requestMSG);
void PostProcess(IMessage requestMSG, IMessage returnMSG);
}
}
二,真实代理的实现
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Services;
using LYG.Share .Interface ;
namespace LYG.Share.AOP.Proxies
{
public abstract class AspectProxy : RealProxy, IInterceptor
{
private MarshalByRefObject _target = null;
public AspectProxy()
: base()
{
}
public AspectProxy(Type serverType)
: base(serverType)
{
}
public void InitProxyTarget(MarshalByRefObject target)
{
this._target = target;
}
public override IMessage Invoke(IMessage msg)
{
bool useInterception = false;
IMethodCallMessage invoke = (IMethodCallMessage)msg;
foreach (InterceptionAttribute attr in invoke.MethodBase.GetCustomAttributes(false))
{
if (attr != null)
{
if (attr.UseInterception)
{
useInterception = true;
break;
}
}
}
if (useInterception)
{
this.PreProcess(msg);
}
IConstructionCallMessage ctorInvoke = invoke as IConstructionCallMessage;
if (ctorInvoke != null)
{
RealProxy default_proxy = RemotingServices.GetRealProxy(this._target );
default_proxy.InitializeServerObject(ctorInvoke);
MarshalByRefObject tp = (MarshalByRefObject)this.GetTransparentProxy();
return EnterpriseServicesHelper.CreateConstructionReturnMessage(ctorInvoke, tp);
}
IMethodReturnMessage returnMSG = RemotingServices.ExecuteMessage(this._target, invoke);
if (useInterception)
{
this.PostProcess(msg, returnMSG);
}
return returnMSG;
}
#region implemente IInterceptor
public abstract void PreProcess(IMessage requestMSG);
public abstract void PostProcess(IMessage requestMSG, IMessage returnMSG);
#endregion
}
}


