EventBus 是一种事件发布订阅模式,借助 EventBus 我们可以很好的实现组件之间,服务之间,系统之间的解耦以及相互通信的问题。
EventBus 相当于是定义一些抽象接口,可以用 MQ 来实现EventBus
1、模块的预处理模块,定义预处理方法,增加实现ILocalEventHandler,IDistributedEventHandler的服务增加到配置
LocalEventBusOptions、DistributedEventBusOptions,分别存储ITypeList
2、IEventHandle接口,分ILocalEventHandler
////// Handler handles the event by implementing this method. /// /// Event data Task HandleEventAsync(TEvent eventData);
IEventHandlerFactory,负责得到或创建事件处理器,三个实现IocEventHandlerFactory,SingleInstanceHandlerFactory,TransientEventHandlerFactory
IEventHandlerDisposeWrapper GetHandler(); public interface IEventHandlerDisposeWrapper : IDisposable { IEventHandler EventHandler { get; } } public class EventHandlerDisposeWrapper : IEventHandlerDisposeWrapper { public IEventHandler EventHandler { get; } private readonly Action _disposeAction; public EventHandlerDisposeWrapper(IEventHandler eventHandler, Action disposeAction = null) { _disposeAction = disposeAction; EventHandler = eventHandler; } public void Dispose() { _disposeAction?.Invoke(); } }
3、EventBus
:用来发布/订阅/取消订阅事件
public abstract Task PublishAsync(Type eventType, object eventData); public abstract IDisposable Subscribe(Type eventType, IEventHandlerFactory factory); public abstract void Unsubscribe(Func action) where TEvent : class; public abstract void Unsubscribe(Type eventType, IEventHandler handler); public abstract void Unsubscribe(Type eventType, IEventHandlerFactory factory); public abstract void Unsubscribe(Type eventType, IEventHandlerFactory factory); public abstract void UnsubscribeAll(Type eventType);
二、AbpRabbitMqModule
[DependsOn( typeof(AbpJsonModule), typeof(AbpThreadingModule) )] public class AbpRabbitMqModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { var configuration = context.Services.GetConfiguration(); Configure(configuration.GetSection("RabbitMQ")); } public override void OnApplicationShutdown(ApplicationShutdownContext context) { context.ServiceProvider .GetRequiredService () .Dispose(); context.ServiceProvider .GetRequiredService () .Dispose(); }
三、AbpEventBusRabbitMqModule
public override Task PublishAsync(Type eventType, object eventData) { var eventName = EventNameAttribute.GetNameOrDefault(eventType); var body = Serializer.Serialize(eventData); using (var channel = ConnectionPool.Get(RabbitMqEventBusOptions.ConnectionName).CreateModel()) { channel.ExchangeDeclare( RabbitMqEventBusOptions.ExchangeName, "direct", durable: true ); var properties = channel.CreateBasicProperties(); properties.DeliveryMode = RabbitMqConsts.DeliveryModes.Persistent; channel.BasicPublish( exchange: RabbitMqEventBusOptions.ExchangeName, routingKey: eventName, mandatory: true, basicProperties: properties, body: body ); } return Task.CompletedTask; }
public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory) { var handlerFactories = GetOrCreateHandlerFactories(eventType); handlerFactories.Add(factory); if (handlerFactories.Count == 1) //TODO: Multi-threading! { Consumer.BindAsync(EventNameAttribute.GetNameOrDefault(eventType)); } return new EventHandlerFactoryUnregistrar(this, eventType, factory); }
一、AbpLocalEventBusOptions,AbpDistributedEventBusOptions
IEventHandler是一个空方法,分为ILocalEventHandler
具有HandleEventAsync(EventType eventData))方法
保存着IEventHandler的实现类型,它通过OnRegistered遍历IServiceCollection服务的委托方法,将ILocalEventHandler
将IDistributedEventHandler<EventType>保存在AbpDistributedEventBusOptions下列表里
而ActionEventHandle
二、IEventBus,它执行的是发布事件,订阅和取消订阅,EventBus是抽象方法,它的实现有NullDistributedEventBus, 这个不注入容器的
它的实现方法将Option的IEventHandler列表方法,将IEventHandle
(1)、Local
(1)LocalBus:ISingletonDependency
订阅方法:保存EventType,以及工厂方法保存在字典里
protected ConcurrentDictionary> HandlerFactories { get; }
IEventHandleFactory工厂方法GetHandler(),IsInFactories(List(IEventHandlerFactory)),有以下3个
>>SingleInstanceHandlerFactory:
IEventHandle来自外部赋值,每次执行都是使用同一个实例
Subscribe(Type eventType, IEventHandler handler)
Subscribe(TEvent委托,使用是的ActionEventHandler )
public IEventHandlerDisposeWrapper GetHandler()
{
return new EventHandlerDisposeWrapper(HandlerInstance);
}
>>TransientEventHandlerFactory:每次都创建
Subscribe()
protected virtual IEventHandler CreateHandler() { return (IEventHandler) Activator.CreateInstance(HandlerType); } public virtual IEventHandlerDisposeWrapper GetHandler() { var handler = CreateHandler(); return new EventHandlerDisposeWrapper( handler, () => (handler as IDisposable)?.Dispose() ); }
>>IocEventHandlerFactory,Option的默认,在容器里依赖注入服务
Subscribe(Type eventType, IEventHandlerFactory factory)
public IEventHandlerDisposeWrapper GetHandler()
{
var scope = ScopeFactory.CreateScope();
return new EventHandlerDisposeWrapper(
(IEventHandler) scope.ServiceProvider.GetRequiredService(HandlerType),
() => scope.Dispose()
);
}
如果EventType是泛型,泛型的参数只有一个,而且这个泛型是继承自IEventDataWithInheritableGenericArgument,实现之一==>entityEventData
entityChangedEventData
EntityChangingEventData
EntityChangeReport 三个List,在AbpDbContext的SaveChangesAsync进行创建,赋值
1、EntityChangeEntry (类型是否Created、Updated、Deleted),使用的是options.EtoMappings,若没有,使用是 EntityEto
EntityCreatedEto
2、DomainEvents (LocalEvent)
3、DistributedEvents: 使用的Eto,在聚合根手工赋值,不是使用automaper
LocalBus提交的类型是EntityCreatingEventData<>,EntityCreatedEventData<>
DistributedEventBus提交是EntityCreatedEto<>,EntityUpdatedEto<>,EntityDeletedEto<>
依赖EntityToEtoMapper如何将entity转成dto,再发送到EventBus里
private void ConfigureDistributedEventBus()
{
Configure<AbpDistributedEventBusOptions>(options =>
{
options.EtoMappings.Add();
});
}
另外是LocalEvent、DistributedEvents
TEntity泛型参数的BaseType,也要执行一次
直到底层Object(Object是一切对象的基型),也要执行
if (eventType.GetTypeInfo().IsGenericType &&
eventType.GetGenericArguments().Length == 1 &&
typeof(IEventDataWithInheritableGenericArgument).IsAssignableFrom(eventType))
{
var genericArg = eventType.GetGenericArguments()[0];
var baseArg = genericArg.GetTypeInfo().BaseType;
if (baseArg != null)
{
var baseEventType = eventType.GetGenericTypeDefinition().MakeGenericType(baseArg); var constructorArgs = ((IEventDataWithInheritableGenericArgument)eventData).GetConstructorArgs(); var baseEventData = Activator.CreateInstance(baseEventType, constructorArgs); await PublishAsync(baseEventType, baseEventData); } }
将Option的handler订阅在EventBus里
protected virtual void SubscribeHandlers(ITypeListhandlers) { foreach (var handler in handlers) { var interfaces = handler.GetInterfaces(); foreach (var @interface in interfaces) { if (!typeof(IEventHandler).GetTypeInfo().IsAssignableFrom(@interface)) { continue; } var genericArgs = @interface.GetGenericArguments(); if (genericArgs.Length == 1) { Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceScopeFactory, handler)); } } } }
取消订阅:取消对应类型TEvent,ACtion方法==》ActionHandle处理Handle ====>针对SingleInstanceHandlerFactory
工厂方法,取消所有订阅,=》对列表的Factories
public abstract void Unsubscribe(Func action) where TEvent : class;
public abstract void Unsubscribe(Type eventType, IEventHandler handler); public abstract void Unsubscribe(Type eventType, IEventHandlerFactory factory); public abstract void UnsubscribeAll(Type eventType);
(2)Distributed
1)LocalDistributedEventBus,它是TryRegister方法,它是SingletonDependency方法,它暴露是的服务接口是IDistributedEventBus以LocalDistributedEventBus
并没有继承EventBus抽象方法
三、Publish方法
Task PublishAsync(Type eventType, object eventData);
Task PublishAsync(TEvent eventData)
where TEvent : class;
执行ILocalEventHandler和 IDistributedEventHandler方法
查找对应EventType有多少个可执行的注册的IEventHandleFactory, 每个EventType有多个List
还需注意其基类也要执行(见下红色),比如执行是EntityCreatedEventData,其下的EntityChangedEventData也应该执行
protected override IEnumerableGetHandlerFactories(Type eventType) { var handlerFactoryList = new List (); foreach (var handlerFactory in HandlerFactories.Where(hf => ShouldTriggerEventForHandler(eventType, hf.Key))) { handlerFactoryList.Add(new EventTypeWithEventHandlerFactories(handlerFactory.Key, handlerFactory.Value)); } return handlerFactoryList.ToArray(); }
private static bool ShouldTriggerEventForHandler(Type targetEventType, Type handlerEventType)
{
//Should trigger same type
if (handlerEventType == targetEventType)
{
return true;
}
//Should trigger for inherited types
if (handlerEventType.IsAssignableFrom(targetEventType))
{
return true;
}
return false; }
await new SynchronizationContextRemover();
foreach (var handlerFactories in GetHandlerFactories(eventType))
{
foreach (var handlerFactory in handlerFactories.EventHandlerFactories)
{
await TriggerHandlerAsync(handlerFactory, handlerFactories.EventType, eventData, exceptions);
}
}
protected virtual async Task TriggerHandlerAsync(IEventHandlerFactory asyncHandlerFactory, Type eventType, object eventData, Listexceptions) { using (var eventHandlerWrapper = asyncHandlerFactory.GetHandler()) { try { var handlerType = eventHandlerWrapper.EventHandler.GetType(); if (ReflectionHelper.IsAssignableToGenericType(handlerType, typeof(ILocalEventHandler<>))) { var method = typeof(ILocalEventHandler<>) .MakeGenericType(eventType) .GetMethod( nameof(ILocalEventHandler
四、RabbbitMQ