C#消息事件封装-创新互联

本人一直认为AS3的事件处理机制很是给力 , 今天鼓捣了出来并完美得通过了测试。在AS3中使用函数addEventListener添加事件侦听,用removeEventListener移除事件侦听。着用封装的一个类库可以彻底地终结消息传递中无规则,无规律的混乱状态,从而达到代码逻辑清晰性。改起来也相当简单(做过程序员的都懂)。

成都创新互联公司专注于泊头企业网站建设,成都响应式网站建设公司,成都做商城网站。泊头网站建设公司,为泊头等地区提供建站服务。全流程按需网站建设,专业设计,全程项目跟踪,成都创新互联公司专业和态度为您提供的服务

关于此类库的实现原理 , 其实使用的是委托(delegate),让侦听函数(观察者)挂载到此委托上,当然消息有不同的类型,如windows系统中有单击,双击,右击等不同的事件类型,在这个类库里面都有实现。

首先,需要指出:

IEventType    ( 所有事件类型的接口 )

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MsgEventLib.com
{
    public interface IEventType
    {
        /// 
        /// 类的类型
        /// 
        Type EventMainType { get; }
        String GetEventTypeName(string type);
    }
}

思想:事件类型以 类的Type.Name + "_" + 事件名称 。 以GetEventTypeName方法实现。

传递的消息体:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MsgEventLib.com
{
    public class BaseEvent
    {
        public BaseEvent(string eventType, object sender, object msg)
        {
            this.eventType = eventType;
            this.sender = sender;
            this.msg = msg;
        }
        private string @eventType;
        public string EventType
        {
            set { this.eventType = value; }
            get { return this.eventType; }
        }
        private object @sender;
        public Object Sender 
        {
            set { this.sender = value; }
            get { return this.sender; }
        }
        private object @msg;
        public object Msg
        {
            set { this.msg = value; }
            get { return this.msg; }
        }
    }
}

其中:eventType为事件类型名称 GetEventTypeName , Sender为发送者 , Msg为消息体

事件侦听管理器的实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MsgEventLib.com
{
    public sealed class EventListener : IEventListener
    {
        private static IEventListener @instance;
        public static IEventListener Instance
        {
            get {
                if (instance == null) instance = new EventListener();
                return instance;
            }
        }
        private Dictionary @listeners;
        private EventListener()
        {
            @listeners = new Dictionary();
        }
        public void AddEventListener(string type, DeListener myListener)
        {
            if (!@listeners.ContainsKey(type))
                @listeners.Add(type, myListener);
            else
                @listeners[type] += myListener;
        }
        public void RemoveEventListener(string type, DeListener myListener)
        {
            if (@listeners.ContainsKey(type))
            {
                @listeners[type] -= myListener;
                if (@listeners[type] == null)
                    @listeners.Remove(type);
            }
        }
        public void RemoveAllEventListener()
        {
            if (@listeners != null && @listeners.Count > 0)
            {
                List keys = new List(@listeners.Keys);//获得所有的键值
                for (int j = 0; j < keys.Count; j++)
                {
                    if (@listeners[keys[j]] != null)
                    {
                        Delegate[] des = @listeners[keys[j]].GetInvocationList();
                        if (des != null && des.Length > 0)
                        {
                            for (int i = 0; i < des.Length; i++)
                            {
                                @listeners[keys[j]] -= des[i] as DeListener;
                            }
                        }
                    }
                    @listeners.Remove(keys[j]);
                }
            }
        }
        public DeListener GetDeListenerByType(string type)
        {
            if (@listeners != null && @listeners.ContainsKey(type))
            {
                return @listeners[type];
            }
            return null;
        }
        public void Destory()
        {
            this.RemoveAllEventListener();
            if (@instance != null) @instance = null;
        }
    }
}

值得注意的是 , 字典 : key为事件类型(GetEventTypeName) , value为委托(可能有多个挂载/观察者)

关于事件发送者(主题)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MsgEventLib.com
{
    public sealed class EventDispacterManager : IEventDispacterManager
    {
        private static IEventDispacterManager @instance;
        public static IEventDispacterManager Instance
        {
            get
            {
                if (instance == null) instance = new EventDispacterManager();
                return instance;
            }
        }
        public void Dispatch(string type , BaseEvent @myevent)
        {
            DeListener target = EventListener.Instance.GetDeListenerByType(type);
            if (target != null)
            {
                target(@myevent);
            }
        }
    }
}

测试的结果

1 , 事件类型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MsgEventLib.com;
namespace TestA.com
{
    public class MyEventType : IEventType
    {
        private static MyEventType @instance;
        public static MyEventType Instance
        {
            get {
                if (@instance == null) @instance = new MyEventType();
                return @instance;
            }
        }
        public Type EventMainType
        {
            get { return typeof(MyEventType); }
        }
        public string GetEventTypeName(string type)
        {
            return this.EventMainType.Name + "_" + type;
        }
        public static string CLOSE_WINDOWS = "CLOSE_WINDOWS";
        public static string OTHRT_TYPE = "OTHRT_TYPE";
    }
}

2 , 3个类(侦听着)

①:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MsgEventLib.com;
namespace TestA.com
{
    public sealed class Listeners
    {
        public Listeners()
        { 
            string type = MyEventType.Instance.GetEventTypeName(MyEventType.CLOSE_WINDOWS);
            EventListener.Instance.AddEventListener(type, this.Li);
        }
        private void Li(BaseEvent e)
        {
            Console.WriteLine("Listeners 触发了Event {0} ", e.Msg);
        }
    }
}

②:

using MsgEventLib.com;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestA.com
{
    public sealed class Lis2
    {
        public Lis2()
        {
            string type = MyEventType.Instance.GetEventTypeName(MyEventType.CLOSE_WINDOWS);
            EventListener.Instance.AddEventListener(type, this.Li);
        }
        private void Li(BaseEvent e)
        {
            Console.WriteLine("Lis2 触发了Event {0} ", e.Msg);
        }
        public void RemoveLis()
        { 
            string type = MyEventType.Instance.GetEventTypeName(MyEventType.CLOSE_WINDOWS);
            EventListener.Instance.RemoveEventListener(type, this.Li);
            Console.WriteLine("Lis2 移除了事件侦听!");
        }
    }
}

③:

using MsgEventLib.com;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestA.com
{
    public sealed class Lis3
    {
        public Lis3()
        {
            string type = MyEventType.Instance.GetEventTypeName(MyEventType.OTHRT_TYPE);
            EventListener.Instance.AddEventListener(type, this.Li);
        }
        private void Li(BaseEvent e)
        {
            Console.WriteLine("Lis3 触发了Event {0} ", e.Msg);
        }
    }
}

事件发送者

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MsgEventLib.com;
namespace TestA.com
{
    public sealed class Dispatch
    {
        public void Dis()
        { 
            string type = MyEventType.Instance.GetEventTypeName(MyEventType.CLOSE_WINDOWS);
            EventDispacterManager.Instance.Dispatch(type,
                new BaseEvent(type, this, "Event_关闭你的窗口"));
        }
    }
}

测试:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TestA.com;

namespace TestA
{
   public class Program
   {
       static void Main(string[] args)
       {
           Dispatch di = new Dispatch();
           Listeners li = new Listeners();
           Lis2 li2 = new Lis2();
           Lis3 li3 = new Lis3();
           di.Dis();
           li2.RemoveLis();
           di.Dis();

           Console.Read();

       }
   }
}

结果:

C#消息事件封装

因为Lis3侦听的不是事件CLOSE_WINDOWS , 既不会触发 。 因为Lis2移除了事件,所以第二次不会触发。

这只是部分大码。详细请见附件。

附件:http://down.51cto.com/data/2366478

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


当前题目:C#消息事件封装-创新互联
文章URL:http://ybzwz.com/article/dhieop.html