Dispenser/DispenserCommon/Events/EventManager.cs

59 lines
2.6 KiB
C#
Raw Normal View History

2024-08-16 07:20:09 +00:00
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 });
}
}
}
}
}