Spring系列(3/1)---交互的一种尝试

前一篇,我们知道可以利用委托和代理来实现为目标类增加额外责任,这里我们先用一个简单的例子说明如何去实现.

//目标类,有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)如果动态生成类采用这种方式,有一个非常大的问题,就是上面代码红色部分无法实现,因为代理类是动态生成的,写代码的时候是编译过不去的。

     实例化代理类比较容易实现,但事件挂接比较没法,没法静态写。

那怎么办呢?下一篇我们就来改进,一点点的去完成动态代理的要求。

 

后记:因为非虚方法不能作为监视的方法,因此我前面的动态代码生成时可以把这些方法除掉。同时执行方法的方式也可以直接改成调用,不用采用反射方式。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值