59 lines
2.6 KiB
C#
59 lines
2.6 KiB
C#
using System.Reflection;
|
|
using DispenserCommon.Ioc;
|
|
using DispenserCommon.Utils;
|
|
|
|
namespace DispenserCommon.Events;
|
|
|
|
/// <summary>
|
|
/// 通过事件管理者的方式来扫描系统内所有添加了注解的事件订阅者,并注册到事件总线上
|
|
/// </summary>
|
|
public class EventManager
|
|
{
|
|
/// <summary>
|
|
/// 扫描所有带有 EventListener 注解的类,并注册到事件总线上
|
|
/// Action回调方法 为 所有带有 EventAction 注解的方法
|
|
/// 方法必须为两个参数的委托,第一个参数为事件类型,第二个参数为事件数据
|
|
/// </summary>
|
|
/// <exception cref="Exception"></exception>
|
|
public static void RegListeners()
|
|
{
|
|
var listeners = AppDomain.CurrentDomain.GetAssemblies()
|
|
.SelectMany(a => a.GetTypes()
|
|
.Where(t => t.GetCustomAttributes(typeof(EventListener), true).Length > 0
|
|
|| t.GetCustomAttributes(typeof(Component), true).Length > 0))
|
|
.ToList();
|
|
|
|
foreach (var listener in listeners)
|
|
{
|
|
// 扫描当前类中所有的带有 EventAction 特性的方法
|
|
var methods = listener
|
|
.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance)
|
|
.Where(m => m.GetCustomAttributes(typeof(EventAction), true).Length > 0)
|
|
.ToList();
|
|
foreach (var method in methods)
|
|
{
|
|
var handler = method.GetCustomAttribute<EventAction>();
|
|
|
|
// 获取方法的参数类型
|
|
var parameters = method.GetParameters();
|
|
if (parameters.Length != 2) throw new Exception("订阅方法的参数必须为两个,第一个参数为事件类型,第二个参数为事件数据");
|
|
|
|
// 获取参数类型
|
|
var parameterType = parameters[1].ParameterType;
|
|
|
|
var types = handler?.Types;
|
|
if (types == null) continue;
|
|
foreach (var type in types)
|
|
{
|
|
var actionType = typeof(Action<,>).MakeGenericType(typeof(EventType), parameterType);
|
|
|
|
var instance = ServiceLocator.GetService(listener);
|
|
var @delegate = method.CreateDelegate(actionType, instance);
|
|
var eventBus = typeof(EventBus<>).MakeGenericType(parameterType);
|
|
var addEventHandler = eventBus.GetMethod("AddEventHandler");
|
|
addEventHandler?.Invoke(null, new object[] { type, @delegate });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |