本節目錄 原理介紹 Abp源碼分析 代碼實現 原理介紹 事件匯流排大致原理: (1) 在事件匯流排內部維護著一個事件與事件處理程式相映射的字典。 (2) 利用反射,事件匯流排會將實現了IEventHandler的處理程式與相應事件關聯到一起,相當於實現了事件處理程式對事件的訂閱。 (3) 當發佈事件時,事
本節目錄
原理介紹
事件匯流排大致原理:
(1) 在事件匯流排內部維護著一個事件與事件處理程式相映射的字典。
(2) 利用反射,事件匯流排會將實現了IEventHandler的處理程式與相應事件關聯到一起,相當於實現了事件處理程式對事件的訂閱。
(3) 當發佈事件時,事件匯流排會從字典中找出相應的事件處理程式,然後利用反射去調用事件處理程式中的方法。
Abp源碼分析
1.AbpKernelModule的Initialize方法
2.EventBusInstaller的Install方法
3.Kernel_ComponentRegistered
以上將事件註冊完成了.
剩下就需要如何觸發了.
觸發實際上是寫在代碼里的,最終調用的其實還是EventBus.Trigger()
代碼實現
看完Abp的實現,關鍵點還是反射以及IoC註冊對象事件的攔截.
先上實現效果:
interface IPerson { void Say(); } class Person : IPerson { public IEventBus EventBus { get; set; } public void Say() { var str = "Say"; Console.WriteLine(str); EventBus.Trigger(typeof(SayEventData), this, new SayEventData() { Content = str }); } }
定義上面需要的EventData,實際這是事件基類.
[Serializable] public abstract class EventData : IEventData { public DateTime EventTime { get; set; } /// <summary> /// The object which triggers the event (optional). /// </summary> public object EventSource { get; set; } protected EventData() { EventTime = DateTime.Now; } } public interface IEventData { DateTime EventTime { get; set; } object EventSource { get; set; } }
自定義事件,繼承事件基類,可以添加事件需要傳遞的數據.
public class SayEventData : EventData { public string Content { get; set; } }
定義IEventHandle,實際這是事件處理程式,一個事件一般對應多個事件處理程式.
public interface IEventHandler { } public interface IEventHandler<in TEventData> : IEventHandler { /// <summary> /// Handler handles the event by implementing this method. /// </summary> /// <param name="eventData">Event data</param> void HandleEvent(TEventData eventData); }
自定義的EventHandle,各種事件訂閱器.
public class SayEvent : IEventHandler<SayEventData> { public void HandleEvent(SayEventData eventData) { Console.WriteLine("進入事件啦:" + eventData.Content); } }
事件匯流排EventBus,管理事件的中心.可以細化介面.
public interface IEventBus { void Register(Type eventType, IEventHandler handler); void Trigger(Type eventType, object eventSource, IEventData eventData); }
EventBus實現,核心是反射調用事件處理程式.
public class EventBus : IEventBus { public static EventBus Default { get { return DefaultInstance; } } private static readonly EventBus DefaultInstance = new EventBus(); private readonly Dictionary<Type, List<IEventHandler>> _eventHandlers; public EventBus() { _eventHandlers = new Dictionary<Type, List<IEventHandler>>(); } public void Register(Type eventType, IEventHandler handler) { GetOrCreateHandlerFactories(eventType).Add(handler); } private List<IEventHandler> GetOrCreateHandlerFactories(Type eventType) { List<IEventHandler> handlers; if (!_eventHandlers.TryGetValue(eventType, out handlers)) { _eventHandlers[eventType] = handlers = new List<IEventHandler>(); } return handlers; } public void Trigger(Type eventType, object eventSource, IEventData eventData) { eventData.EventSource = eventSource; var handles = GetOrCreateHandlerFactories(eventType); if (handles.Count > 0) { foreach (var eventHandler in handles) { if (eventHandler == null) { throw new Exception("Registered event handler for event type " + eventType.Name + " does not implement IEventHandler<" + eventType.Name + "> interface!"); } //eventHandler. var handlerType = typeof(IEventHandler<>).MakeGenericType(eventType); handlerType .GetMethod("HandleEvent", BindingFlags.Public | BindingFlags.Instance, null, new[] { eventType }, null) .Invoke(eventHandler, new object[] { eventData }); } } } }
執行,來測試是否通了.
private static IEventBus _eventBus; static void Main(string[] args) { var container = IocManager.Instance.IocContainer; container.Register(Component.For<IEventBus>().Instance(EventBus.Default)); _eventBus = container.Resolve<IEventBus>(); container.Kernel.ComponentRegistered += Kernel_ComponentRegistered; //在Abp中,由於註冊了所有ITransientDependency,所以這2個不需要手動註冊 container.Register(Component.For<Person, IPerson>()); container.Register(Component.For<IEventHandler<SayEventData>, SayEvent>()); container.Resolve<IPerson>().Say(); Console.ReadKey(); }
註冊事件的綁定
private static void Kernel_ComponentRegistered(string key, IHandler handler) { if (!typeof(IEventHandler).IsAssignableFrom(handler.ComponentModel.Implementation)) { return; } var interfaces = handler.ComponentModel.Implementation.GetInterfaces(); foreach (var @interface in interfaces) { if (!typeof(IEventHandler).IsAssignableFrom(@interface)) { continue; } var genericArgs = @interface.GetGenericArguments(); if (genericArgs.Length == 1) { //_eventBus.Register(genericArgs[0], handler.ComponentModel.Implementation.CreateInstance<IEventHandler>()); _eventBus.Register(genericArgs[0], (IEventHandler)IocManager.Instance.IocContainer.Resolve(handler.ComponentModel.Implementation)); } } }
至此,事件成功執行
本文地址:http://www.cnblogs.com/neverc/p/5254859.html