接上篇:
4、我们知道我们进行动态代理的目的是为了附加责任,也就是在目标类方法执行的时候,我们能增加一些附加的功能。我们前面的模型虽然可以达到这个目的,但通信信息不够。观察者虽然可以获取目标类,但无法知道当前执行的方法和参数值,这在有些情况下虽然没什么不利,但既然我们的目标其实就是监视目标类的方法的执行,能有目标类执行方法时的方法信息和当前实际参数的信息,当然是更好了,为此,我们可以专门增加一个参数型来封装这些,便于调用统一:
public interface INotifyInvocation
{
object Target { get; set; }
object Proceed();
object[] Params{get;}//可选
MethodInfo MethodInfo{get;}//可选
}
//上面的接口是否公布方法信息和参数,需看自己的需要决定。
public class NotifyInvocation : INotifyInvocation
{
#region INotifyInvocation成员
private object _target;
private MethodInfo _currMethod;
private object[] _parmas;
public NotifyInvocation (object target, MethodInfo method, object[] parmas)
{
_target = target;
_currMethod = method;
_parmas = parmas;
}
public object Target
{
get
{
return _target;
}
set
{
_target = value;
}
}
object[] Params
{
get{return _params;}
}
MethodInfo MethodInfo{
get{return _currMethod;
}
public object Proceed()
{
return _currMehtod.Invoke(_target, _parmas);
}
#endregion
类NotifyInvocation作为交互时的参数类型,注意这里的参数有执行方法,这个方法就是简单的调用目标类的相应方法,这个主要提供给附加责任类来执行目标类的方法,而在代理类中一般还有一个调用,那个是给目标类原来的调用者的。这样做当然有好处,但如果执行这个方法本身会影响目标类的状态,那就要注意了,因为附加责任类的多次调用,可能会使得本来的调用者得到不可预期的结果,因此,我们采用这种方式的时候一定要求目标方法是调用无状态的,既多次调用不影响原调用者的调用结果。
............待续