[Architect] Abp 框架原理解析(2) EventBus
本节目录
原理介绍
事件总线大致原理:
(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
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。