Исходный код вики Добавление ссылки после создания Activity
Редактировал(а) Alexandr Fokin 2022/12/07 07:48
Скрыть последних авторов
author | version | line-number | content |
---|---|---|---|
![]() |
1.2 | 1 | [[Reflection | Рефлексия>>doc:Разработка.NET.C#.Рантайм и типы.Reflection | Рефлексия .WebHome]] |
2 | |||
![]() |
2.1 | 3 | [[Expression tree>>doc:Разработка.NET.C#.Рантайм и типы.Expression tree | Деревья выражений.WebHome]] |
![]() |
1.2 | 4 | |
![]() |
2.2 | 5 | runtime/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagLinkedList.cs |
6 | [[https:~~/~~/github.com/dotnet/runtime/blob/7bac4e8fa611eb02ac1bd27b97a8570cbf321437/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagLinkedList.cs>>https://github.com/dotnet/runtime/blob/7bac4e8fa611eb02ac1bd27b97a8570cbf321437/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagLinkedList.cs]] | ||
7 | |||
![]() |
1.2 | 8 | ---- |
9 | |||
10 | {{code language="c#"}} | ||
11 | public static class ActivityExtensions | ||
12 | { | ||
13 | private static readonly Action<Activity, ActivityLink> ActivityAddLink1; | ||
14 | private static readonly Action<Activity, ActivityLink> ActivityAddLink2; | ||
15 | |||
16 | static ActivityExtensions() | ||
17 | { | ||
18 | var activityType = typeof(Activity); | ||
19 | var linkType = typeof(ActivityLink); | ||
20 | |||
21 | var linksField = activityType.GetField( | ||
22 | name: "_links", | ||
23 | bindingAttr: BindingFlags.Instance | BindingFlags.NonPublic | ||
24 | )!; | ||
25 | |||
26 | var collectionType = linksField.FieldType; | ||
27 | var collectionAddMethod = collectionType.GetMethod( | ||
28 | name: "Add", | ||
29 | bindingAttr: BindingFlags.Instance | BindingFlags.Public | ||
30 | )!; | ||
31 | |||
32 | |||
33 | { | ||
34 | var constructorMethod = collectionType.GetConstructor( | ||
35 | types: linkType.OneItemArray() | ||
36 | )!; | ||
37 | |||
38 | |||
39 | ActivityAddLink2 = (a, e) => | ||
40 | { | ||
41 | var parameter = ((object)e).OneItemArray(); | ||
42 | var collection = linksField.GetValue(a); | ||
43 | |||
44 | if (collection == null) | ||
45 | { | ||
46 | collection = constructorMethod.Invoke(parameter); | ||
47 | linksField.SetValue(a, collection); | ||
48 | } | ||
49 | else | ||
50 | { | ||
51 | collectionAddMethod.Invoke( | ||
52 | collection, | ||
53 | parameter | ||
54 | ); | ||
55 | } | ||
56 | }; | ||
57 | } | ||
58 | |||
59 | { | ||
60 | var constructorMethod = collectionType.GetConstructor( | ||
61 | types: linkType.OneItemArray() | ||
62 | )!; | ||
63 | |||
64 | |||
65 | var activityParameter = Expression.Parameter(activityType); | ||
66 | var linkParameter = Expression.Parameter(linkType); | ||
67 | |||
68 | |||
69 | var collectionExp = Expression.Field(activityParameter, linksField); | ||
70 | |||
71 | var addExp = Expression.Call(collectionExp, collectionAddMethod, linkParameter); | ||
72 | |||
73 | var constructorExp = Expression.New(constructorMethod, linkParameter); | ||
74 | var constructorAndSetExp = Expression.Assign(collectionExp, constructorExp); | ||
75 | |||
76 | |||
77 | var addMethodLambda = Expression.Lambda<Action<Activity, ActivityLink>>( | ||
78 | body: addExp, | ||
79 | parameters: new ParameterExpression[] { activityParameter, linkParameter } | ||
80 | ); | ||
81 | var createCollectionMethodLambda = Expression.Lambda<Action<Activity, ActivityLink>>( | ||
82 | body: constructorAndSetExp, | ||
83 | parameters: new ParameterExpression[] { activityParameter, linkParameter } | ||
84 | ); | ||
85 | |||
86 | |||
87 | Action<Activity, ActivityLink> addMethod = addMethodLambda.Compile(); | ||
88 | Action<Activity, ActivityLink> createCollectionMethod = createCollectionMethodLambda.Compile(); | ||
89 | |||
90 | |||
91 | |||
92 | ActivityAddLink1 = (a, e) => | ||
93 | { | ||
94 | if (a.Links.Any()) | ||
95 | { | ||
96 | addMethod(a, e); | ||
97 | } | ||
98 | else | ||
99 | { | ||
100 | createCollectionMethod(a, e); | ||
101 | } | ||
102 | }; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | [Obsolete] | ||
107 | public static void AddLink( | ||
108 | this Activity activity, | ||
109 | in ActivityLink link | ||
110 | ) | ||
111 | { | ||
112 | ActivityAddLink1( | ||
113 | activity, | ||
114 | link | ||
115 | ); | ||
116 | } | ||
117 | |||
118 | public static void AddLink( | ||
119 | this Activity activity, | ||
120 | Activity linkActivity, | ||
121 | params (string Key, string Value)[] tags | ||
122 | ) | ||
123 | { | ||
124 | var link = new ActivityLink( | ||
125 | linkActivity.Context, | ||
126 | new ActivityTagsCollection( | ||
127 | tags.Select( | ||
128 | e => new KeyValuePair<string, object?>(e.Key, e.Value) | ||
129 | ) | ||
130 | ) | ||
131 | ); | ||
132 | |||
133 | AddLink( | ||
134 | activity, | ||
135 | link | ||
136 | ); | ||
137 | } | ||
138 | } | ||
139 | {{/code}} |