C#实战反射、事件、抽象工厂、发布订阅模式

来源:互联网 发布:adobe旗下软件 编辑:程序博客网 时间:2024/06/05 15:28

最近一直在做一个新系统,其中小部分任务需要用到事件监听触发的过程。自己先练练手。


首先是,Listener的代码,监听者监听到事件后需要作出的反应。

namespace ConsoleApplication1.ObserverDesignModelTest{    public class WIPListener    {        public void StartWork(EventData data)        {            Console.WriteLine("WIP处理开工事件...");        }        public void ReportWork(EventData data)        {            Console.WriteLine("WIP处理报工事件...");        }        public void FinalInspect(EventData data)        {            Console.WriteLine("WIP处理终检事件...");        }    }}
再来一个事件数据类,在我们的系统里,这种类就是数据库数据一个映射。我们可以把它理解为一条数据,一旦生成这个类对象即一条数据,即触发上面的方法。

namespace ConsoleApplication1.ObserverDesignModelTest{    public class EventData    {        public string EventType { get; set; }        public string Name1 { get; set; }        public string Value1 { get; set; }    }}
再来一个抽象事件类及几个具体事件类,用于创建上面的事件数据对象,相当于通过这些不同的类来生成不同类型的数据。

namespace ConsoleApplication1.ObserverDesignModelTest{    public abstract class AbstractEvent    {        public event Action<EventData> TriggerEvent;        public abstract void GetEventInfo(EventData eventData);        public virtual EventData CreateEventData(Dictionary<string, object> dic)        {            var eventData = new EventData();            eventData.Name1 = dic.First().Key;            eventData.Value1 = dic.First().Value.ToString();            return eventData;        }        public void Trigger(EventData eventData)        {            TriggerEvent(eventData);        }    }}namespace ConsoleApplication1.ObserverDesignModelTest{    class StartWorkEvent:AbstractEvent    {        public override void GetEventInfo(EventData eventData)        {            Console.WriteLine(eventData.EventType+"事件参数名:" + eventData.Name1 + ",参数值:" + eventData.Value1);        }        public override EventData CreateEventData(Dictionary<string, object> dic)        {            Console.WriteLine("创建开工事件数据...");            return base.CreateEventData(dic);        }    }}namespace ConsoleApplication1.ObserverDesignModelTest{    class ReportWorkEvent:AbstractEvent    {        public override void GetEventInfo(EventData eventData)        {            Console.WriteLine(eventData.EventType + "事件参数名:" + eventData.Name1 + ",参数值:" + eventData.Value1);        }        public override EventData CreateEventData(Dictionary<string, object> dic)        {            Console.WriteLine("创建报工事件数据...");            return base.CreateEventData(dic);        }    }}namespace ConsoleApplication1.ObserverDesignModelTest{    class FinalInspectEvent:AbstractEvent    {        public override void GetEventInfo(EventData eventData)        {            Console.WriteLine(eventData.EventType + "事件参数名:" + eventData.Name1 + ",参数值:" + eventData.Value1);        }        public override EventData CreateEventData(Dictionary<string, object> dic)        {            Console.WriteLine("创建终检事件数据...");            return base.CreateEventData(dic);        }    }}
然后,我们通过反射的方式,创建我们想要的事件类,就是上面的三种。
namespace ConsoleApplication1.ObserverDesignModelTest{    public class EventGenerator    {        public static AbstractEvent CreateEvent<T>(Dictionary<string, object> dic) where T : AbstractEvent        {            var type = typeof (T);            var aEvent = Activator.CreateInstance<T>();            return aEvent;        }    }}
然后,就是发布信息的Publisher了,给它也设三个方法,对应上述的类和方法。注意,不同的方法注册不同的事件,可以传参数。

namespace ConsoleApplication1.ObserverDesignModelTest{    public class PCMPublisher    {        WIPListener wipListener=new WIPListener();        public void StartWork()        {            Console.WriteLine("PCM开工!");            var dic = new Dictionary<string, object>();            dic.Add("OrderNo","OrderNo001");            var aEvent = EventGenerator.CreateEvent<StartWorkEvent>(dic);            aEvent.TriggerEvent += wipListener.StartWork;            var eventData = aEvent.CreateEventData(dic);            eventData.EventType = "开工";            aEvent.GetEventInfo(eventData);            aEvent.Trigger(eventData);        }        public void ReportWork()        {            Console.WriteLine("PCM报工!");            var dic = new Dictionary<string, object>();            dic.Add("OperationBillNo", "OperationBillNo001");            var aEvent = EventGenerator.CreateEvent<StartWorkEvent>(dic);            aEvent.TriggerEvent += wipListener.ReportWork;            var eventData = aEvent.CreateEventData(dic);            eventData.EventType = "报工";            aEvent.GetEventInfo(eventData);            aEvent.Trigger(eventData);        }        public void FinalInspect()        {            Console.WriteLine("PCM终检!");            var dic = new Dictionary<string, object>();            dic.Add("FinalInspectRecord", "FinalInspectRecord001");            var aEvent = EventGenerator.CreateEvent<StartWorkEvent>(dic);            aEvent.TriggerEvent += wipListener.FinalInspect;            var eventData = aEvent.CreateEventData(dic);            eventData.EventType = "终检";            aEvent.GetEventInfo(eventData);            aEvent.Trigger(eventData);        }    }}
最后,我们在Main方法中调用这些发布者的方法,看看能不能触发监听者们的回应。

        public static void Main(string[] args)        {            TestEvent1();            Console.Read();        }        public static void TestEvent1()        {            PCMPublisher publisher=new PCMPublisher();            publisher.StartWork();            Console.WriteLine("\n过了10分钟...");            publisher.ReportWork();            Console.WriteLine("\n又过了10分钟...");            publisher.FinalInspect();        }
运行一下,成功



谢谢大家!