前面一篇,我们写了一个代理类,可以实现一些功能,但作为动态代理类的原型,还是有问题的。我们来改进一下原来的类,如下:
/// <summary>
/// 代理类,从AClass继承.这是必须的,否则AClass能用的地方, ProxyAClass1却没法用.这里的改进主要是将需要切入的委托,采用构造参数传递进去,有利于动态构造实例。
/// </summary>
public class ProxyAClass1 : AClass
{
private AClass _target;
private List<InteractorDelegate> _InteractAtAList = null;
private List<InteractorDelegate> _InteractAtB1List = null;
private List<InteractorDelegate> _InteractAtB2List = null;
private List<InteractorDelegate> _InteractAtC1List = null;
private List<InteractorDelegate> _InteractAtC2List = null;
private List<InteractorDelegate> _InteractAtDList = null;
private List<InteractorDelegate> _InteractAtEList = null;
/// <summary>
/// 构造函数,需传入目标类实例.
/// </summary>
/// <param name="target"></param>
public ProxyAClass1(AClass target,List<InteractorDelegate> A,List<InteractorDelegate> B1,
List<InteractorDelegate> B2,List<InteractorDelegate> C1,
List<InteractorDelegate> C2,List<InteractorDelegate> D,
List<InteractorDelegate> E)
{
_target = target;
this._InteractAtAList = A;
this._InteractAtB1List = B1;
this._InteractAtB2List = B2;
this._InteractAtC1List = C1;
this._InteractAtC2List = C2;
this._InteractAtDList = D;
this._InteractAtEList = E;
}
/// <summary>
/// 执行方法实例.这里的代码与前一篇的相同,这里不再赘述。
/// </summary>
public override void Save()
{
//
}
}
public class TestClass
{
public static void Test()
{
AClass A = new AClass();
List<InteractorDelegate> theAs = new List<InteractorDelegate>();
theAs.Add(new InteractorDelegate(PA_InteractAtA));
ProxyAClass1 PA = new ProxyAClass1(A,theAs,.....);
//......
}
static bool PA_InteractAtB1(object Target, object Sender)
{
//do something
return true;
}
static bool PA_InteractAtA(object Target, object Sender)
{
//do something
return false;
}
}
// 红色的代码其实可以动态完成,因为我们知道构造函数,也知道代理类名,就可以利用反射机制动态创建这个类的实例。到现在为止,这个代理类已经可以完全动态生成,利用第1篇或者Emit的IL指令注入方式都可以。利用这种方式实现AOP编程,虽然看起来还不够专业,但功能上还是完全可以实现。
为什么看起来不够专业呢?我们仔细看看这种应用方式,还是有些别扭,主要有以下四点:
1)没有创建代理类的工厂,如果每次都需要自己动态创建,一是会使得用户使用不是很方便,二是用户需要知道的太多,实例化代理类怎么来说也是比较专业的事情,由工厂类去负责,责任单一会更好一些。
2)虽然委托简单,但一般情况下,附加责任类,比如日志类,安全检查类等如果用委托来挂接也有点显得不太地道。
3)切入点委托的增加方式也显得有点笨拙。
4)决定是否继续执行依赖于代理类的控制,虽然前面的实现中,我们利用返回值也是一种控制的办法有,但有的时候,我们也希望将决定权委托给外部附加责任类来直接完成,这样控制更灵活。
下一篇,我们就上述的一些问题继续改进,争取实现的更好些。