mirror of https://github.com/abpframework/abp.git
10 changed files with 130 additions and 33 deletions
@ -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 }); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.Abp.EventBus; |
|||
|
|||
public interface IEventHandlerInvoker |
|||
{ |
|||
Task InvokeAsync(IEventHandler eventHandler, object eventData); |
|||
} |
|||
Loading…
Reference in new issue