ABP之事件总线(2)

在上一篇文章中,我们复习了一下事件的经典的发布订阅模式,同时对是事件源和时间处理逻辑进行抽象统一,用起来也没有问题。但是还是有很多的问题,比如说我们Handle方法其实是违背了单一性的原则的,里面混杂了各个EventData的处理逻辑,这个方法将会越来越大,越来越慢,看着越来越难受。好,那么先解决今天的第一个问题。既然我们前面为了单一化原则,分别定义了不同的xxEventData,那么我们可以同样的定义不同的xxEventHandler.

创建不同的Handler

        public class FishingEventHandler : IEventHandler<FishEventData>
        {
            public void Handle(FishEventData eventData)
            {
                Console.WriteLine("小猫说:");
                Console.WriteLine("我吃了{0}斤鱼",eventData.FishWeight);
            }
        }
        public class MouseEventHandler : IEventHandler<MouseEventData>
        {
            public void Handle(MouseEventData eventData)
            {
                Console.WriteLine("小猫说:");
                Console.WriteLine("我抓到了{0}老鼠", eventData.MouseName);
            }
       }

实现猫捉老鼠

  static void Main(string[] args)
        {

            Cat c1 = new Cat();
            Mouse m1 = new Mouse("1号老鼠");

            //订阅事件
            // m1.selfEventHandler += c1.Handle;
            m1.selfEventHandler += new MouseEventHandler().Handle;
            //触发事件
            m1.Comming(m1.Name);
           
            Console.ReadLine();
        }

到了这里,可能会感到疑问了,我们做了这么多的工作,又回到了最初的起点???事件的处理逻辑还是得重新写。。。。但是!!!!有没有发现一个问题,我们把事件整个的脱离出来了,不再依赖于猫(订阅者),而是直接订阅事件,关键是还有一个关键的发现,那就是我们统一了事件的处理逻辑方法的名称,统一为Handle。这样大大方便了我们的开发,以后我们编写事件的时候,只需要编写对应的xxxEventData和xxxEventHandler就可以了,是不是很方便!是不是有一种解除耦合的感觉!

上面的这行代码是我们手动注册我们的事件处理逻辑,现在问题来了刚才我们写的是猫捉老鼠的处理逻辑,现在来了,狗捉老鼠,牛捉老鼠,大象捉老鼠。。。。此时创建了DogMouseEventHandler:IEventHandler<MouseEventData>、NiuMouseEventHandler:IEventHandler<MouseEventData>、ElephantMouseEventHandler:IEventHandler<MouseEventData>

 m1.selfEventHandler += new DogMouseEventHandler().Handle;
 m1.selfEventHandler += new NiuMouseEventHandler().Handle;
 m1.selfEventHandler += new ElephantMouseEventHandler().Handle;
如果我们再动态的添加很多,此时我们的代码还是需要修改。。。。。那么如何解决这个问题呢?也就是如何代替显示的注册,而是直接自动的动态的注册。那就只能从程序集入手了。。。用到的技术也就是我们常说的反射。

所以我们重新修改Mouse类
    public  class Mouse
    {
     
      
        //声明事件委托
        public event MouserEventHandler selfEventHandler;
        public Mouse(string name)
        {
            this.Name = name;
            var asm = Assembly.GetExecutingAssembly();
            foreach (var type in asm.GetTypes())
            {
                //判断当前的类型是否实现了IEventHandler接口
                if (typeof(IEventHandler).IsAssignableFrom(type))
                {
                    //获取该type实现了泛型的IEventhandler接口
                    var handlerInterface = type.GetInterface("IEventHandler`1");
                    if (handlerInterface == null)
                        continue;
                    var arg = handlerInterface.GetGenericArguments()[0];
                    if (arg.Equals(typeof(MouseEventData)))
                    {
                        var handler = Activator.CreateInstance(type) as IEventHandler<MouseEventData>;
                        this.selfEventHandler += handler.Handle;
                    }
                }
            }
        }
        public void Comming(string name )
        {
            Console.WriteLine("老鼠说:\n");

            Console.WriteLine("我的名字是{0},I am Comming!", name);
            //触发事件
            selfEventHandler(new MouseEventData() { MouseName = name});
        }
        public string Name { get; set; }
        
    }

上面的代码中我们将Mouse类的构造函数进行重写,在构造函数中使用反射的方式实现事件逻辑的注册。

上面标注的地方由两个需要注意的地方:1.必须是IEventHandler`1,而不是IEventHandler,如果使用IEventHander,那么IEventHandler<TEventData>也将会被获取到,此时获取参数是没有的,所以会出现索引超出的错误

                                                               2.IEventHandler`1,这是固定的获取泛型接口的方法

                                                              

此时我们的猫捉老鼠

    class Program
    {
        static void Main(string[] args)
        {

            Cat c1 = new Cat();
            Mouse m1 = new Mouse("1号老鼠");

            //订阅事件
            // m1.selfEventHandler += c1.Handle;
            // m1.selfEventHandler += new MouseEventHandler().Handle;
            //触发事件
            m1.Comming(m1.Name);
           
            Console.ReadLine();
        }
      
    }

运行一下:

今天那就先到这里了。

 

 



 

 

posted @ 2018-04-04 00:17  善良的小赵  阅读(653)  评论(0编辑  收藏  举报