简介
项目中的事件派发系统,会动态生成唯一id并赋值给对应字段,当发生报错时,日志仅打印事件id,并不知道具体事件类型,故作此拓展。
方案思路
- 构建一个新的特性,将使用有事件id的类全部使用此特性注册一次
- 获取到所有程序集,并将注册过此特性的类全部持有到
- 在初始化时,将所有事件id记录一次
- 后续查找时,直接使用事件id进行匹配,并将事件类型进行打印
使用技术
- 反射
- 特性
代码示例
/// <summary>
/// 事件Debug特性类(用于寻找那些注册有事件的类)
/// </summary>
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method|AttributeTargets.Field|AttributeTargets.Constructor|AttributeTargets.Property)]
public class EventDebugInfo : Attribute
{
private Type type;
public EventDebugInfo(Type type)
{
this.type = type;
}
public Type Type
{
get { return type; }
}
}
/// <summary>
/// 记录事件id信息的字典
/// </summary>
private static Dictionary<int,string> eventIdDict = new Dictionary<int,string>();
/// <summary>
/// 打印事件信息
/// </summary>
/// <param name="eventId">全局唯一事件id</param>
public static void LogEventInfo(int eventId)
{
//仅在第一次打印时初始化字典
if (eventIdDict.Count <= 0)
{
Assembly currentAssembly = Assembly.GetExecutingAssembly();
foreach (Type type in currentAssembly.GetTypes())
{
if (type.IsDefined(typeof(EventDebugInfo)))
{
FieldInfo[] fieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.Static);
foreach (FieldInfo fieldInfo in fieldInfos)
{
object fieldValue = fieldInfo.GetValue(null);
if (int.TryParse(fieldValue.ToString(), out int value))
{
string eventStr = $"EventDebugManager: Id{eventId} {type.Name}.{fieldInfo.Name}";
if (!eventIdDict.TryAdd(value, eventStr))
{
eventIdDict.Remove(value);
}
}
}
}
}
}
//字典中获取debug信息,并打印
if (eventIdDict.TryGetValue(eventId, out string eventName))
{
Debug.LogError(eventName);
}
}
标签:反查,type,AttributeTargets,public,事件,Type,id
From: https://www.cnblogs.com/comradexiao/p/18466994