-
Notifications
You must be signed in to change notification settings - Fork 4.7k
/
CustomReflectionContext.cs
158 lines (133 loc) · 5.46 KB
/
CustomReflectionContext.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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
using System.Reflection.Context.Custom;
using System.Reflection.Context.Projection;
using System.Reflection.Context.Virtual;
namespace System.Reflection.Context
{
internal sealed class IdentityReflectionContext : ReflectionContext
{
public override Assembly MapAssembly(Assembly assembly) { return assembly; }
public override TypeInfo MapType(TypeInfo type) { return type; }
}
public abstract partial class CustomReflectionContext : ReflectionContext
{
private readonly ReflectionContextProjector _projector;
protected CustomReflectionContext() : this(new IdentityReflectionContext()) { }
protected CustomReflectionContext(ReflectionContext source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
SourceContext = source;
_projector = new ReflectionContextProjector(this);
}
public override Assembly MapAssembly(Assembly assembly)
{
if (assembly is null)
{
throw new ArgumentNullException(nameof(assembly));
}
return _projector.ProjectAssemblyIfNeeded(assembly);
}
public override TypeInfo MapType(TypeInfo type)
{
if (type is null)
{
throw new ArgumentNullException(nameof(type));
}
return _projector.ProjectTypeIfNeeded(type);
}
protected virtual IEnumerable<object> GetCustomAttributes(MemberInfo member, IEnumerable<object> declaredAttributes)
{
return declaredAttributes;
}
protected virtual IEnumerable<object> GetCustomAttributes(ParameterInfo parameter, IEnumerable<object> declaredAttributes)
{
return declaredAttributes;
}
// The default implementation of GetProperties: just return an empty list.
protected virtual IEnumerable<PropertyInfo> AddProperties(Type type)
{
// return an empty enumeration
yield break;
}
protected PropertyInfo CreateProperty(
Type propertyType,
string name,
Func<object, object?>? getter,
Action<object, object?>? setter)
{
return new VirtualPropertyInfo(
name,
propertyType,
getter,
setter,
null,
null,
null,
this);
}
protected PropertyInfo CreateProperty(
Type propertyType,
string name,
Func<object, object?>? getter,
Action<object, object?>? setter,
IEnumerable<Attribute>? propertyCustomAttributes,
IEnumerable<Attribute>? getterCustomAttributes,
IEnumerable<Attribute>? setterCustomAttributes)
{
return new VirtualPropertyInfo(
name,
propertyType,
getter,
setter,
propertyCustomAttributes,
getterCustomAttributes,
setterCustomAttributes,
this);
}
internal IEnumerable<PropertyInfo> GetNewPropertiesForType(CustomType type)
{
// We don't support adding properties on these types.
if (type.IsInterface || type.IsGenericParameter || type.HasElementType)
yield break;
// Passing in the underlying type.
IEnumerable<PropertyInfo> newProperties = AddProperties(type.UnderlyingType);
// Setting DeclaringType on the user provided virtual properties.
foreach (PropertyInfo prop in newProperties)
{
if (prop == null)
throw new InvalidOperationException(SR.InvalidOperation_AddNullProperty);
VirtualPropertyBase? vp = prop as VirtualPropertyBase;
if (vp == null || vp.ReflectionContext != this)
throw new InvalidOperationException(SR.InvalidOperation_AddPropertyDifferentContext);
if (vp.DeclaringType == null)
vp.SetDeclaringType(type);
else if (!vp.DeclaringType.Equals(type))
throw new InvalidOperationException(SR.InvalidOperation_AddPropertyDifferentType);
yield return prop;
}
}
internal IEnumerable<object> GetCustomAttributesOnMember(MemberInfo member, IEnumerable<object> declaredAttributes, Type attributeFilterType)
{
IEnumerable<object> attributes = GetCustomAttributes(member, declaredAttributes);
return AttributeUtils.FilterCustomAttributes(attributes, attributeFilterType);
}
internal IEnumerable<object> GetCustomAttributesOnParameter(ParameterInfo parameter, IEnumerable<object> declaredAttributes, Type attributeFilterType)
{
IEnumerable<object> attributes = GetCustomAttributes(parameter, declaredAttributes);
return AttributeUtils.FilterCustomAttributes(attributes, attributeFilterType);
}
internal Projector Projector
{
get
{
return _projector;
}
}
internal ReflectionContext SourceContext { get; }
}
}