Skip to content

Commit eaf7688

Browse files
committed
Expand public reflection interfaces and APIs
Introduce IConstructorDataView, IMethodDataView, and IParameterizedMemberDataView as public interfaces for reflection-based data access and invocation. Promote key methods and properties in ConstructorData, MethodData, and EventData from internal to public, enabling external consumers to invoke and inspect constructors, methods, and events. Refactor IMemberDataView and IEventDataView to align with new interfaces. Modernize collection initialization and simplify descriptor structs for improved clarity and performance. These changes provide a more robust, type-safe, and discoverable reflection API.
1 parent c112874 commit eaf7688

13 files changed

Lines changed: 258 additions & 233 deletions

‎src/BionicCode.Utilities.Reflection/ConstructorData.cs‎

Lines changed: 88 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -5,156 +5,155 @@
55

66
internal sealed class ConstructorData : ParameterizedMemberData
77
{
8-
private string? displayName;
9-
private string? shortDisplayName;
10-
private string? fullyQualifiedDisplayName;
11-
private string? signature;
12-
private string? shortSignature;
13-
private string? shortCompactSignature;
14-
private string? fullyQualifiedSignature;
15-
private string? fullyQualifiedRuntimeSignature;
16-
private string? runtimeSignature;
17-
private string? runtimeShortSignature;
18-
private string? runtimeShortCompactSignature;
19-
private SymbolAttributes symbolAttributes;
20-
private AccessModifier accessModifier;
21-
private ParameterList? parameters;
8+
private string? _displayName;
9+
private string? _shortDisplayName;
10+
private string? _fullyQualifiedDisplayName;
11+
private string? _signature;
12+
private string? _shortSignature;
13+
private string? _shortCompactSignature;
14+
private string? _fullyQualifiedSignature;
15+
private string? _fullyQualifiedRuntimeSignature;
16+
private string? _runtimeSignature;
17+
private string? _runtimeShortSignature;
18+
private string? _runtimeShortCompactSignature;
19+
private SymbolAttributes _symbolAttributes;
20+
private AccessModifier _accessModifier;
21+
private ParameterList? _parameters;
2222
private bool? _hasParamsParameter;
23-
private bool? isStatic;
23+
private bool? _isStatic;
2424
private bool? _isPublic;
2525
private bool? _isPrivate;
2626
private bool? _isAssembly;
2727
private bool? _isFamily;
2828
private bool? _isFamilyOrAssembly;
2929
private bool? _isFamilyAndAssembly;
30-
private Func<object?[], object>? invocator;
31-
private string? assemblyName;
32-
private SymbolComponentInfo? symbolComponentInfo;
30+
private Func<object?[], object>? _invocator;
31+
private string? _assemblyName;
32+
private SymbolComponentInfo? _symbolComponentInfo;
3333

34-
internal ConstructorData(ConstructorInfo constructorInfo, SymbolReflectionInfoCacheKey symbolInfoDataCacheKey)
35-
: base(constructorInfo, SymbolKind.MemberConstructor, symbolInfoDataCacheKey)
34+
internal ConstructorData(SymbolReflectionInfoCacheKey symbolInfoDataCacheKey)
35+
: base(symbolInfoDataCacheKey)
3636
{
37-
ArgumentNullException.ThrowIfNull(constructorInfo, nameof(constructorInfo));
37+
ArgumentNullExceptionAdvanced.ThrowIfDefault(symbolInfoDataCacheKey);
3838

39-
Handle = constructorInfo.MethodHandle;
39+
Handle = symbolInfoDataCacheKey.ConstructorDescriptor.ConstructorInfo.MethodHandle;
40+
ConstructorInfo = symbolInfoDataCacheKey.ConstructorDescriptor.ConstructorInfo;
4041
}
4142

42-
internal ConstructorInfo GetConstructorInfo()
43-
=> (ConstructorInfo)MethodInfo.GetMethodFromHandle(Handle, DeclaringTypeHandle)!;
43+
public ConstructorInfo ConstructorInfo { get; }
4444

45-
internal override MethodBase GetMethodBase()
46-
=> GetConstructorInfo();
45+
public override MethodBase GetMethodBase()
46+
=> ConstructorInfo;
4747

4848
protected override MemberInfo GetMemberInfo()
49-
=> GetConstructorInfo();
49+
=> ConstructorInfo;
5050

51-
internal object Invoke(params object?[] arguments)
51+
public object Invoke(params object?[] arguments)
5252
{
5353
// TODO::Implement fast invocator pattern
54-
if (invocator is null)
54+
if (_invocator is null)
5555
{
5656
InitializeInvocator();
5757
}
5858

59-
return invocator.Invoke(arguments);
59+
return _invocator.Invoke(arguments);
6060
}
6161

62-
internal Func<object[], object> GetInvocator()
62+
public Func<object[], object> GetInvocator()
6363
{
64-
if (invocator is null)
64+
if (_invocator is null)
6565
{
6666
InitializeInvocator();
6767
}
6868

69-
return invocator;
69+
return _invocator!;
7070
}
7171

7272
private void InitializeInvocator()
73-
=> invocator = invocationArguments => GetConstructorInfo().Invoke(invocationArguments);
73+
=> _invocator = ConstructorInfo.Invoke;
7474

75-
internal override RuntimeMethodHandle Handle { get; }
76-
internal new RuntimeTypeHandle DeclaringTypeHandle { get; }
75+
public override RuntimeMethodHandle Handle { get; }
7776

78-
internal override AccessModifier AccessModifier => accessModifier is AccessModifier.Undefined
79-
? (accessModifier = ConstructorData.GetAccessModifierInternal(this))
80-
: accessModifier;
77+
public override AccessModifier AccessModifier => _accessModifier is AccessModifier.Undefined
78+
? (_accessModifier = ConstructorData.GetAccessModifierInternal(this))
79+
: _accessModifier;
8180

82-
internal override ParameterList Parameters
83-
=> parameters ??= ParameterListBuilder.Create(this);
81+
public override ParameterList Parameters
82+
=> _parameters ??= ParameterListBuilder.Create(this);
8483

85-
internal override bool HasParamsParameter
84+
public override bool HasParamsParameter
8685
=> _hasParamsParameter ??= Parameters.HasItems && Parameters[^1].IsParams;
8786

88-
internal override SymbolAttributes SymbolAttributes => symbolAttributes is SymbolAttributes.Undefined
89-
? (symbolAttributes = ConstructorData.GetAttributesInternal(this))
90-
: symbolAttributes;
87+
public override SymbolAttributes SymbolAttributes => _symbolAttributes is SymbolAttributes.Undefined
88+
? (_symbolAttributes = ConstructorData.GetAttributesInternal(this))
89+
: _symbolAttributes;
9190

92-
internal override SymbolComponentInfo SymbolComponentInfo
93-
=> symbolComponentInfo ??= SymbolSignatureGenerator.ToSignatureComponentsInternal(this, isFullyQualifiedName: false, isDeclaringTypeIncluded: false, isCompact: false);
91+
public override SymbolComponentInfo SymbolComponentInfo
92+
=> _symbolComponentInfo ??= SymbolSignatureGenerator.ToSignatureComponentsInternal(this, isFullyQualifiedName: false, isDeclaringTypeIncluded: false, isCompact: false);
9493

95-
internal override string Signature
96-
=> signature ??= SymbolSignatureGenerator.ToSignatureNameInternal(this, isFullyQualifiedName: false, isDeclaringTypeIncluded: true, isCompact: false, isRuntimeSymbol: false);
94+
public override string Signature
95+
=> _signature ??= SymbolSignatureGenerator.ToSignatureNameInternal(this, isFullyQualifiedName: false, isDeclaringTypeIncluded: true, isCompact: false, isRuntimeSymbol: false);
9796

98-
internal override string ShortSignature
99-
=> shortSignature ??= SymbolSignatureGenerator.ToSignatureNameInternal(this, isFullyQualifiedName: false, isDeclaringTypeIncluded: false, isCompact: false, isRuntimeSymbol: false);
97+
public override string ShortSignature
98+
=> _shortSignature ??= SymbolSignatureGenerator.ToSignatureNameInternal(this, isFullyQualifiedName: false, isDeclaringTypeIncluded: false, isCompact: false, isRuntimeSymbol: false);
10099

101-
internal override string ShortCompactSignature
102-
=> shortCompactSignature ??= SymbolSignatureGenerator.ToSignatureNameInternal(this, isFullyQualifiedName: false, isDeclaringTypeIncluded: false, isCompact: true, isRuntimeSymbol: false);
100+
public override string ShortCompactSignature
101+
=> _shortCompactSignature ??= SymbolSignatureGenerator.ToSignatureNameInternal(this, isFullyQualifiedName: false, isDeclaringTypeIncluded: false, isCompact: true, isRuntimeSymbol: false);
103102

104-
internal override string FullyQualifiedSignature
105-
=> fullyQualifiedSignature ??= SymbolSignatureGenerator.ToSignatureNameInternal(this, isFullyQualifiedName: true, isDeclaringTypeIncluded: true, isCompact: false, isRuntimeSymbol: false);
103+
public override string FullyQualifiedSignature
104+
=> _fullyQualifiedSignature ??= SymbolSignatureGenerator.ToSignatureNameInternal(this, isFullyQualifiedName: true, isDeclaringTypeIncluded: true, isCompact: false, isRuntimeSymbol: false);
106105

107-
internal override string FullyQualifiedRuntimeSignature
108-
=> fullyQualifiedRuntimeSignature ??= SymbolSignatureGenerator.ToSignatureNameInternal(this, isFullyQualifiedName: true, isDeclaringTypeIncluded: true, isCompact: false, isRuntimeSymbol: true);
106+
public override string FullyQualifiedRuntimeSignature
107+
=> _fullyQualifiedRuntimeSignature ??= SymbolSignatureGenerator.ToSignatureNameInternal(this, isFullyQualifiedName: true, isDeclaringTypeIncluded: true, isCompact: false, isRuntimeSymbol: true);
109108

110-
internal override string RuntimeSignature
111-
=> runtimeSignature ??= SymbolSignatureGenerator.ToSignatureNameInternal(this, isFullyQualifiedName: false, isDeclaringTypeIncluded: true, isCompact: false, isRuntimeSymbol: true);
109+
public override string RuntimeSignature
110+
=> _runtimeSignature ??= SymbolSignatureGenerator.ToSignatureNameInternal(this, isFullyQualifiedName: false, isDeclaringTypeIncluded: true, isCompact: false, isRuntimeSymbol: true);
112111

113-
internal override string RuntimeShortSignature
114-
=> runtimeShortSignature ??= SymbolSignatureGenerator.ToSignatureNameInternal(this, isFullyQualifiedName: false, isDeclaringTypeIncluded: false, isCompact: false, isRuntimeSymbol: true);
112+
public override string RuntimeShortSignature
113+
=> _runtimeShortSignature ??= SymbolSignatureGenerator.ToSignatureNameInternal(this, isFullyQualifiedName: false, isDeclaringTypeIncluded: false, isCompact: false, isRuntimeSymbol: true);
115114

116-
internal override string RuntimeShortCompactSignature
117-
=> runtimeShortCompactSignature ??= SymbolSignatureGenerator.ToSignatureNameInternal(this, isFullyQualifiedName: false, isDeclaringTypeIncluded: false, isCompact: true, isRuntimeSymbol: true);
115+
public override string RuntimeShortCompactSignature
116+
=> _runtimeShortCompactSignature ??= SymbolSignatureGenerator.ToSignatureNameInternal(this, isFullyQualifiedName: false, isDeclaringTypeIncluded: false, isCompact: true, isRuntimeSymbol: true);
118117

119-
internal override string DisplayName
120-
=> displayName ??= SymbolSignatureGenerator.ToDisplayNameInternal(this, isFullyQualifiedName: false, isGenericTypeParameterIncluded: true, isDeclaringTypeIncluded: true);
118+
public override string DisplayName
119+
=> _displayName ??= SymbolSignatureGenerator.ToDisplayNameInternal(this, isFullyQualifiedName: false, isGenericTypeParameterIncluded: true, isDeclaringTypeIncluded: true);
121120

122-
internal override string ShortDisplayName
123-
=> shortDisplayName ??= SymbolSignatureGenerator.ToDisplayNameInternal(this, isFullyQualifiedName: false, isGenericTypeParameterIncluded: true, isDeclaringTypeIncluded: false);
121+
public override string ShortDisplayName
122+
=> _shortDisplayName ??= SymbolSignatureGenerator.ToDisplayNameInternal(this, isFullyQualifiedName: false, isGenericTypeParameterIncluded: true, isDeclaringTypeIncluded: false);
124123

125-
internal override string FullyQualifiedDisplayName
126-
=> fullyQualifiedDisplayName ??= SymbolSignatureGenerator.ToDisplayNameInternal(this, isFullyQualifiedName: true, isGenericTypeParameterIncluded: true, isDeclaringTypeIncluded: true);
124+
public override string FullyQualifiedDisplayName
125+
=> _fullyQualifiedDisplayName ??= SymbolSignatureGenerator.ToDisplayNameInternal(this, isFullyQualifiedName: true, isGenericTypeParameterIncluded: true, isDeclaringTypeIncluded: true);
127126

128-
internal override string AssemblyName
129-
=> assemblyName ??= DeclaringTypeData.AssemblyName;
127+
public override string AssemblyName
128+
=> _assemblyName ??= DeclaringTypeData.AssemblyName;
130129

131-
internal override bool IsStatic
132-
=> isStatic ??= GetConstructorInfo().IsStatic;
130+
public override bool IsStatic
131+
=> _isStatic ??= ConstructorInfo.IsStatic;
133132

134-
internal override bool IsPublic
135-
=> _isPublic ??= GetConstructorInfo().IsPublic;
133+
public override bool IsPublic
134+
=> _isPublic ??= ConstructorInfo.IsPublic;
136135

137-
internal override bool IsPrivate
138-
=> _isPrivate ??= GetConstructorInfo().IsPrivate;
136+
public override bool IsPrivate
137+
=> _isPrivate ??= ConstructorInfo.IsPrivate;
139138

140-
internal override bool IsAssembly
141-
=> _isAssembly ??= GetConstructorInfo().IsAssembly;
139+
public override bool IsAssembly
140+
=> _isAssembly ??= ConstructorInfo.IsAssembly;
142141

143-
internal override bool IsFamily
144-
=> _isFamily ??= GetConstructorInfo().IsFamily;
142+
public override bool IsFamily
143+
=> _isFamily ??= ConstructorInfo.IsFamily;
145144

146-
internal override bool IsFamilyOrAssembly
147-
=> _isFamilyOrAssembly ??= GetConstructorInfo().IsFamilyOrAssembly;
145+
public override bool IsFamilyOrAssembly
146+
=> _isFamilyOrAssembly ??= ConstructorInfo.IsFamilyOrAssembly;
148147

149-
internal override bool IsFamilyAndAssembly
150-
=> _isFamilyAndAssembly ??= GetConstructorInfo().IsFamilyAndAssembly;
148+
public override bool IsFamilyAndAssembly
149+
=> _isFamilyAndAssembly ??= ConstructorInfo.IsFamilyAndAssembly;
151150

152-
internal override ParameterizedSymbolKind ParameterizedSymbolKind
151+
public override ParameterizedSymbolKind ParameterizedSymbolKind
153152
=> ParameterizedSymbolKind.MemberConstructor;
154153

155-
internal override RuntimeTypeHandle DeclaringTypeHandle { get; }
156-
internal override bool IsExplicitInterfaceImplementation { get; }
157-
internal override RuntimeTypeHandle ImplementingTypeHandle { get; }
154+
public override RuntimeTypeHandle DeclaringTypeHandle { get; }
155+
public override bool IsExplicitInterfaceImplementation { get; }
156+
public override RuntimeTypeHandle ImplementingTypeHandle { get; }
158157

159158
/// <summary>
160159
/// Determines the symbol attributes for a constructor based on the specified constructor data.

‎src/BionicCode.Utilities.Reflection/EventData.cs‎

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,12 @@ internal EventData(SymbolReflectionInfoCacheKey symbolInfoDataCacheKey)
4747

4848
_descriptor = symbolInfoDataCacheKey.EventDescriptor;
4949
EventInfo = symbolInfoDataCacheKey.EventDescriptor.EventInfo;
50-
IsExplicitInterfaceImplementation = _descriptor.IsExplicitInterfaceImplementation;
51-
DeclaringTypeHandle = _descriptor.DeclaringTypeHandle;
52-
ImplementingTypeHandle = _descriptor.ImplementingTypeHandle;
5350
}
5451

5552
protected override MemberInfo GetMemberInfo()
5653
=> EventInfo;
5754

58-
internal object? RaiseEvent(object? target, params object?[]? arguments)
55+
public object? RaiseEvent(object? target, params object?[]? arguments)
5956
{
6057
ThrowIfTargetIsNullOrTargetTypeIsNotMatchingDeclaringTypeForInstanceMember(target);
6158
ThrowIfInvalidMethodArguments(arguments);
@@ -124,23 +121,23 @@ private void ThrowIfInvalidMethodArguments(object?[]? args)
124121
}
125122

126123
/// <inheritdoc/>
127-
internal override AccessModifier AccessModifier => _accessModifier is AccessModifier.Undefined
124+
public override AccessModifier AccessModifier => _accessModifier is AccessModifier.Undefined
128125
? (_accessModifier = EventData.GetAccessModifierInternal(this))
129126
: _accessModifier;
130127

131-
internal void AddEventHandler(object eventSource, Delegate handler)
128+
public void AddEventHandler(object eventSource, Delegate handler)
132129
=> AddMethodData.Invoke(eventSource, handler);
133130

134-
internal void AddEventHandler<TEventSource>(TEventSource eventSource, Delegate handler)
131+
public void AddEventHandler<TEventSource>(TEventSource eventSource, Delegate handler)
135132
=> AddMethodData.Invoke(eventSource, handler);
136133

137-
internal void RemoveEventHandler(object eventSource, Delegate handler)
134+
public void RemoveEventHandler(object eventSource, Delegate handler)
138135
=> RemoveMethodData.Invoke(eventSource, handler);
139136

140-
internal void RemoveEventHandler<TEventSource>(TEventSource eventSource, Delegate handler)
137+
public void RemoveEventHandler<TEventSource>(TEventSource eventSource, Delegate handler)
141138
=> RemoveMethodData.Invoke(eventSource, handler);
142139

143-
internal MethodData AddMethodData
140+
public MethodData AddMethodData
144141
=> _addMethodData ??= IsExplicitInterfaceImplementation
145142
? MethodInfo.GetMethodFromHandle(_descriptor.AddAccessorImplementationMethodHandle) is MethodInfo explicitImplementationAccessor
146143
? SymbolReflectionInfoCache.GetOrCreateSymbolReflectionInfoCacheEntry(explicitImplementationAccessor)
@@ -149,7 +146,7 @@ internal MethodData AddMethodData
149146
? SymbolReflectionInfoCache.GetOrCreateSymbolReflectionInfoCacheEntry(methodInfo)
150147
: throw new NotSupportedException($"The underlying '{typeof(EventInfo).FullName}' for event '{EventInfo.Name}' does not have an add method.");
151148

152-
internal MethodData RemoveMethodData
149+
public MethodData RemoveMethodData
153150
=> _removeMethodData ??= IsExplicitInterfaceImplementation
154151
? MethodInfo.GetMethodFromHandle(_descriptor.RemoveAccessorImplementationMethodHandle) is MethodInfo explicitImplementationAccessor
155152
? SymbolReflectionInfoCache.GetOrCreateSymbolReflectionInfoCacheEntry(explicitImplementationAccessor)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace BionicCode.Utilities.Net.Reflection;
2+
3+
public interface IConstructorDataView : IParameterizedMemberDataView, IMemberDataView, ISymbolInfoDataView
4+
{
5+
object Invoke(params object?[] arguments);
6+
}

‎src/BionicCode.Utilities.Reflection/IEventDataView.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
using System;
44

5-
public interface IEventDataView : IMemberDataView
5+
public interface IEventDataView : IMemberDataView, ISymbolInfoDataView
66
{
77
IMethodDataView AddMethodData { get; }
88
bool CanAdd { get; }

‎src/BionicCode.Utilities.Reflection/IMemberDataView.cs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
namespace BionicCode.Utilities.Net.Reflection;
22

33
using System;
4-
using System.Collections.Generic;
54
using System.Reflection;
65
using BionicCode.Utilities.Net;
76

87
public interface IMemberDataView : ISymbolInfoDataView
98
{
9+
MemberInfo GetMemberInfo();
1010
AccessModifier AccessModifier { get; }
11-
new IList<CustomAttributeData> AttributeData { get; }
1211
BindingFlags BindingFlagsVisibilityMask { get; }
13-
RuntimeTypeHandle DeclaringInterfaceHandle { get; }
12+
ITypeDataView DeclaringTypData { get; }
1413
RuntimeTypeHandle DeclaringTypeHandle { get; }
1514
RuntimeTypeHandle ImplementingTypeHandle { get; }
15+
ITypeDataView ImplementingTypData { get; }
1616
bool IsAssembly { get; }
1717
bool IsExplicitInterfaceImplementation { get; }
1818
bool IsFamily { get; }

0 commit comments

Comments
 (0)