前一篇,我们知道可以利用委托和代理来实现为目标类增加额外责任,这里我们先用一个简单的例子说明如何去实现.
//目标类,有3个公共方法,但由于非虚方法无法继承,所以能够切入的只有2个公共虚方法。虽然从生产代理的角度来讲,非虚公共方法也可以截获,
//但要求代理类重写该方法,而一旦重写,根据方法的调用规则,在用目标类型调用这个方法时,其实是调不到代理类中的这个方法的,所以就没有机会截获和监视。
public class AClass
{
public virtual void Save()
{
Console.WriteLine("sadfdsaf");
}
public virtual string GetName(int i)
{
return "tina" + i.ToString();
}
public void DoSomething()
{
Console.WriteLine("AClass DoSomething()");
}
}
/// <summary>
/// 交互委托
/// </summary>
/// <param name="Target">目标类</param>
/// <param name="Sender">代理类</param>
/// <returns>执行结果</returns>
public delegate bool InteractorDelegate(object Target,object Sender);
/// <summary>
/// 代理类,从AClass继承.
/// </summary>
public class ProxyAClass1 : AClass
{
private AClass _target;
private List<IMethodInterceptor> _adviceList = null;
public event InteractorDelegate InteractAtA;
public event InteractorDelegate InteractAtB1;
public event InteractorDelegate InteractAtB2;
public event InteractorDelegate InteractAtC1;
public event InteractorDelegate InteractAtC2;
public event InteractorDelegate InteractAtD;
public event InteractorDelegate InteractAtE;
/// <summary>
/// 构造函数,需传入目标类实例.
/// </summary>
/// <param name="target"></param>
public ProxyAClass1(AClass target)
{
_target = target;
}
/// <summary>
/// 执行方法实例.这里只以一个方法做演示.
/// </summary>
public override void Save()
{
try
{
if (InteractAtA != null)
{
InteractAtA(_target, this);
}
if (InteractAtB1 != null)
{
if (InteractAtB1(_target, this) == true)
{
if (InteractAtB2 != null)
{
InteractAtB2(_target, this);
}
_target.Save();
if (InteractAtC1 != null)
{
InteractAtC1(_target, this);
}
}
}
if (InteractAtC2 != null)
{
InteractAtC2(_target, this);
}
}
catch
{
if (InteractAtD != null)
{
InteractAtD(_target, this);
}
}
finally
{
if (InteractAtE != null)
{
InteractAtE(_target, this);
}
}
}
}
//下面是用法
//测试类.
public class TestClass
{
public static void Test()
{
AClass A = new AClass();
AClass PA = new ProxyAClass1(A);
PA.InteractAtA += new InteractorDelegate(PA_InteractAtA);
PA.InteractAtB1 += new InteractorDelegate(PA_InteractAtB1);
//......
}
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)采用事件,那么多个方法挂接时执行的顺序并不能保证,而且很难实现选票制
2)如果动态生成类采用这种方式,有一个非常大的问题,就是上面代码红色部分无法实现,因为代理类是动态生成的,写代码的时候是编译过不去的。
实例化代理类比较容易实现,但事件挂接比较没法,没法静态写。
那怎么办呢?下一篇我们就来改进,一点点的去完成动态代理的要求。
后记:因为非虚方法不能作为监视的方法,因此我前面的动态代码生成时可以把这些方法除掉。同时执行方法的方式也可以直接改成调用,不用采用反射方式。