-
Notifications
You must be signed in to change notification settings - Fork 523
/
AttributeX.cs
131 lines (112 loc) · 4.95 KB
/
AttributeX.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Reflection;
using NewLife.Reflection;
namespace NewLife;
/// <summary>特性辅助类</summary>
public static class AttributeX
{
#region 静态方法
private static readonly ConcurrentDictionary<String, Object> _asmCache = new();
/// <summary>获取自定义属性,带有缓存功能,避免因.Net内部GetCustomAttributes没有缓存而带来的损耗</summary>
/// <typeparam name="TAttribute"></typeparam>
/// <param name="assembly"></param>
/// <returns></returns>
public static TAttribute[] GetCustomAttributes<TAttribute>(this Assembly assembly)
{
if (assembly == null) return new TAttribute[0];
var key = $"{assembly.FullName}_{typeof(TAttribute).FullName}";
return (TAttribute[])_asmCache.GetOrAdd(key, k =>
{
var atts = assembly.GetCustomAttributes(typeof(TAttribute), true) as TAttribute[];
return atts ?? (new TAttribute[0]);
});
}
/// <summary>获取成员绑定的显示名</summary>
/// <param name="member"></param>
/// <param name="inherit"></param>
/// <returns></returns>
public static String? GetDisplayName(this MemberInfo member, Boolean inherit = true)
{
var att = member.GetCustomAttribute<DisplayNameAttribute>(inherit);
if (att != null && !att.DisplayName.IsNullOrWhiteSpace()) return att.DisplayName;
return null;
}
/// <summary>获取成员绑定的备注</summary>
/// <param name="member"></param>
/// <param name="inherit"></param>
/// <returns></returns>
public static String? GetDescription(this MemberInfo member, Boolean inherit = true)
{
var att2 = member.GetCustomAttribute<DescriptionAttribute>(inherit);
if (att2 != null && !att2.Description.IsNullOrWhiteSpace()) return att2.Description;
return null;
}
/// <summary>获取自定义属性的值。可用于ReflectionOnly加载的程序集</summary>
/// <typeparam name="TAttribute"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <returns></returns>
public static TResult? GetCustomAttributeValue<TAttribute, TResult>(this Assembly target) where TAttribute : Attribute
{
if (target == null) return default;
// CustomAttributeData可能会导致只反射加载,需要屏蔽内部异常
try
{
var list = CustomAttributeData.GetCustomAttributes(target);
if (list == null || list.Count <= 0) return default;
foreach (var item in list)
{
if (typeof(TAttribute) != item.Constructor.DeclaringType) continue;
var args = item.ConstructorArguments;
if (args != null && args.Count > 0) return (TResult?)args[0].Value;
}
}
catch { }
return default;
}
/// <summary>获取自定义属性的值。可用于ReflectionOnly加载的程序集</summary>
/// <typeparam name="TAttribute"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="target">目标对象</param>
/// <param name="inherit">是否递归</param>
/// <returns></returns>
public static TResult? GetCustomAttributeValue<TAttribute, TResult>(this MemberInfo target, Boolean inherit = true) where TAttribute : Attribute
{
if (target == null) return default;
try
{
var list = CustomAttributeData.GetCustomAttributes(target);
if (list != null && list.Count > 0)
{
foreach (var item in list)
{
if (typeof(TAttribute).FullName != item.Constructor.DeclaringType?.FullName) continue;
var args = item.ConstructorArguments;
if (args != null && args.Count > 0) return (TResult?)args[0].Value;
}
}
if (inherit && target is Type type && type.BaseType != null)
{
target = type.BaseType;
if (target != null && target != typeof(Object))
return GetCustomAttributeValue<TAttribute, TResult>(target, inherit);
}
}
catch
{
// 出错以后,如果不是仅反射加载,可以考虑正面来一次
if (!target.Module.Assembly.ReflectionOnly)
{
//var att = GetCustomAttribute<TAttribute>(target, inherit);
var att = target.GetCustomAttribute<TAttribute>(inherit);
if (att != null)
{
var pi = typeof(TAttribute).GetProperties().FirstOrDefault(p => p.PropertyType == typeof(TResult));
if (pi != null) return (TResult?)att.GetValue(pi);
}
}
}
return default;
}
#endregion
}