Browse Source

Enhancement Trigger Event Handler

pull/11232/head
liangshiwei 5 years ago
parent
commit
7f464754be
  1. 6
      framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AzureDistributedEventBus.cs
  2. 6
      framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs
  3. 6
      framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs
  4. 6
      framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs
  5. 6
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs
  6. 28
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs
  7. 26
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventHandlerInvoker.cs
  8. 66
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventHandlerMethodExecutor.cs
  9. 8
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventHandlerInvoker.cs
  10. 5
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs

6
framework/src/Volo.Abp.EventBus.Azure/Volo/Abp/EventBus/Azure/AzureDistributedEventBus.cs

@ -39,13 +39,15 @@ public class AzureDistributedEventBus : DistributedEventBusBase, ISingletonDepen
IOptions<AbpAzureEventBusOptions> abpAzureEventBusOptions,
IAzureServiceBusSerializer serializer,
IAzureServiceBusMessageConsumerFactory messageConsumerFactory,
IPublisherPool publisherPool)
IPublisherPool publisherPool,
IEventHandlerInvoker eventHandlerInvoker)
: base(serviceScopeFactory,
currentTenant,
unitOfWorkManager,
abpDistributedEventBusOptions,
guidGenerator,
clock)
clock,
eventHandlerInvoker)
{
_options = abpAzureEventBusOptions.Value;
_serializer = serializer;

6
framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs

@ -39,14 +39,16 @@ public class KafkaDistributedEventBus : DistributedEventBusBase, ISingletonDepen
IKafkaSerializer serializer,
IProducerPool producerPool,
IGuidGenerator guidGenerator,
IClock clock)
IClock clock,
IEventHandlerInvoker eventHandlerInvoker)
: base(
serviceScopeFactory,
currentTenant,
unitOfWorkManager,
abpDistributedEventBusOptions,
guidGenerator,
clock)
clock,
eventHandlerInvoker)
{
AbpKafkaEventBusOptions = abpKafkaEventBusOptions.Value;
MessageConsumerFactory = messageConsumerFactory;

6
framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs

@ -44,14 +44,16 @@ public class RabbitMqDistributedEventBus : DistributedEventBusBase, ISingletonDe
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager,
IGuidGenerator guidGenerator,
IClock clock)
IClock clock,
IEventHandlerInvoker eventHandlerInvoker)
: base(
serviceScopeFactory,
currentTenant,
unitOfWorkManager,
distributedEventBusOptions,
guidGenerator,
clock)
clock,
eventHandlerInvoker)
{
ConnectionPool = connectionPool;
Serializer = serializer;

6
framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs

@ -38,14 +38,16 @@ public class RebusDistributedEventBus : DistributedEventBusBase, ISingletonDepen
IOptions<AbpRebusEventBusOptions> abpEventBusRebusOptions,
IRebusSerializer serializer,
IGuidGenerator guidGenerator,
IClock clock) :
IClock clock,
IEventHandlerInvoker eventHandlerInvoker) :
base(
serviceScopeFactory,
currentTenant,
unitOfWorkManager,
abpDistributedEventBusOptions,
guidGenerator,
clock)
clock,
eventHandlerInvoker)
{
Rebus = rebus;
Serializer = serializer;

6
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs

@ -22,11 +22,13 @@ public abstract class DistributedEventBusBase : EventBusBase, IDistributedEventB
IUnitOfWorkManager unitOfWorkManager,
IOptions<AbpDistributedEventBusOptions> abpDistributedEventBusOptions,
IGuidGenerator guidGenerator,
IClock clock
IClock clock,
IEventHandlerInvoker eventHandlerInvoker
) : base(
serviceScopeFactory,
currentTenant,
unitOfWorkManager)
unitOfWorkManager,
eventHandlerInvoker)
{
GuidGenerator = guidGenerator;
Clock = clock;

28
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs

@ -22,14 +22,18 @@ public abstract class EventBusBase : IEventBus
protected IUnitOfWorkManager UnitOfWorkManager { get; }
protected IEventHandlerInvoker EventHandlerInvoker { get; }
protected EventBusBase(
IServiceScopeFactory serviceScopeFactory,
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager)
IUnitOfWorkManager unitOfWorkManager,
IEventHandlerInvoker eventHandlerInvoker)
{
ServiceScopeFactory = serviceScopeFactory;
CurrentTenant = currentTenant;
UnitOfWorkManager = unitOfWorkManager;
EventHandlerInvoker = eventHandlerInvoker;
}
/// <inheritdoc/>
@ -210,27 +214,9 @@ public abstract class EventBusBase : IEventBus
using (CurrentTenant.Change(GetEventDataTenantId(eventData)))
{
if (ReflectionHelper.IsAssignableToGenericType(handlerType, typeof(ILocalEventHandler<>)))
{
var method = typeof(ILocalEventHandler<>)
.MakeGenericType(eventType)
.GetMethod(
nameof(ILocalEventHandler<object>.HandleEventAsync),
new[] { eventType }
);
await ((Task)method.Invoke(eventHandlerWrapper.EventHandler, new[] { eventData }));
}
else if (ReflectionHelper.IsAssignableToGenericType(handlerType, typeof(IDistributedEventHandler<>)))
if (ReflectionHelper.IsAssignableToGenericType(handlerType, typeof(ILocalEventHandler<>)) || ReflectionHelper.IsAssignableToGenericType(handlerType, typeof(IDistributedEventHandler<>)))
{
var method = typeof(IDistributedEventHandler<>)
.MakeGenericType(eventType)
.GetMethod(
nameof(IDistributedEventHandler<object>.HandleEventAsync),
new[] { eventType }
);
await ((Task)method.Invoke(eventHandlerWrapper.EventHandler, new[] { eventData }));
await EventHandlerInvoker.InvokeAsync(eventHandlerWrapper.EventHandler, eventData);
}
else
{

26
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventHandlerInvoker.cs

@ -0,0 +1,26 @@
using System;
using System.Collections.Concurrent;
using System.Reflection;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.EventBus;
public class EventHandlerInvoker : IEventHandlerInvoker, ISingletonDependency
{
private const string EventHandlerMethodName = "HandleEventAsync";
private readonly ConcurrentDictionary<Type, EventHandlerMethodExecutor> _executorCache;
public EventHandlerInvoker()
{
_executorCache = new ConcurrentDictionary<Type, EventHandlerMethodExecutor>();
}
public Task InvokeAsync(IEventHandler eventHandler, object eventData)
{
var handleType = eventHandler.GetType();
var executor = _executorCache.GetOrAdd(handleType, type => EventHandlerMethodExecutor.Create(type.GetMethod(EventHandlerMethodName), type.GetTypeInfo()));
return executor.ExecuteAsync(eventHandler, new[] { eventData });
}
}

66
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventHandlerMethodExecutor.cs

@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
namespace Volo.Abp.EventBus;
public class EventHandlerMethodExecutor
{
private readonly MethodExecutorAsync _executorAsync;
private delegate Task MethodExecutorAsync(IEventHandler target, object[] parameters);
public MethodInfo MethodInfo { get; }
public TypeInfo TargetTypeInfo { get; }
private EventHandlerMethodExecutor(MethodInfo methodInfo, TypeInfo targetTypeInfo)
{
if (methodInfo == null)
{
throw new ArgumentNullException(nameof(methodInfo));
}
MethodInfo = methodInfo;
TargetTypeInfo = targetTypeInfo;
_executorAsync = GetExecutorAsync(methodInfo, targetTypeInfo);
}
private static MethodExecutorAsync GetExecutorAsync(MethodInfo methodInfo, TypeInfo targetTypeInfo)
{
var targetParameter = Expression.Parameter(typeof(IEventHandler), "target");
var parametersParameter = Expression.Parameter(typeof(object[]), "parameters");
var paramInfos = methodInfo.GetParameters();
var parameters = new List<Expression>(paramInfos.Length);
for (var i = 0; i < paramInfos.Length; i++)
{
var paramInfo = paramInfos[i];
var valueObj = Expression.ArrayIndex(parametersParameter, Expression.Constant(i));
var valueCast = Expression.Convert(valueObj, paramInfo.ParameterType);
parameters.Add(valueCast);
}
var instanceCast = Expression.Convert(targetParameter, targetTypeInfo.AsType());
var methodCall = Expression.Call(instanceCast, methodInfo, parameters);
var castMethodCall = Expression.Convert(methodCall, typeof(Task));
var lambda = Expression.Lambda<MethodExecutorAsync>(castMethodCall, targetParameter, parametersParameter);
return lambda.Compile();
}
public static EventHandlerMethodExecutor Create(MethodInfo methodInfo, TypeInfo targetTypeInfo)
{
return new EventHandlerMethodExecutor(methodInfo, targetTypeInfo);
}
public Task ExecuteAsync(IEventHandler target, object[] parameters)
{
return _executorAsync(target, parameters);
}
}

8
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventHandlerInvoker.cs

@ -0,0 +1,8 @@
using System.Threading.Tasks;
namespace Volo.Abp.EventBus;
public interface IEventHandlerInvoker
{
Task InvokeAsync(IEventHandler eventHandler, object eventData);
}

5
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs

@ -33,8 +33,9 @@ public class LocalEventBus : EventBusBase, ILocalEventBus, ISingletonDependency
IOptions<AbpLocalEventBusOptions> options,
IServiceScopeFactory serviceScopeFactory,
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager)
: base(serviceScopeFactory, currentTenant, unitOfWorkManager)
IUnitOfWorkManager unitOfWorkManager,
IEventHandlerInvoker eventHandlerInvoker)
: base(serviceScopeFactory, currentTenant, unitOfWorkManager, eventHandlerInvoker)
{
Options = options.Value;
Logger = NullLogger<LocalEventBus>.Instance;

Loading…
Cancel
Save