InternalProxy
Abstract generic base class for creating type-safe proxy wrappers around Unity's internal (non-public) types. Provides cached reflection access to fields, properties, and methods of the proxied type.
Definition
Namespace: Paragon.Editor.LowLevel Assembly: Paragon.Editor.dll
internal abstract class InternalProxy<TProxy> where TProxy : InternalProxy<TProxy>Type Parameters:
TProxy— The concrete proxy subclass (CRTP pattern)
Remarks
InternalProxy<TProxy> enables safe, structured access to Unity's internal types that are normally inaccessible. Rather than scattering reflection calls throughout the codebase, each internal type gets a dedicated proxy class that:
Declares the target type via
[InternalProxyAttribute]Exposes internal members as strongly-typed properties and methods
Caches all
FieldInfo,PropertyInfo, andMethodInfolookups for performance
How It Works
The static constructor reads the [InternalProxyAttribute] from the concrete subclass TProxy to determine the target internal type. All subsequent field/property/method lookups use BindingFlags.Public | NonPublic | Instance | Static and are cached in static dictionaries.
Known Concrete Proxies
13 concrete proxies exist in the codebase, including:
SceneHierarchyWindow— proxiesUnityEditor.SceneHierarchyWindowPackageDatabase— proxiesUnityEditor.PackageManager.UI.Internal.PackageDatabaseProduct,Package,PackageVersion— Package Manager internal typesImportPackageItem,PackageUtility,PackageImport— Package import internals
Quick Lookup
Create a proxy class
Subclass InternalProxy<MyProxy> with [InternalProxy(typeof(TargetType))]
Wrap an existing instance
MyProxy.Proxy(existingObject)
Create a new instance
MyProxy.Instance(constructorArgs)
Read internal field
GetField<T>("fieldName") in proxy
Write internal field
SetField("fieldName", value) in proxy
Read internal property
GetProperty<T>("propName") in proxy
Invoke internal method
InvokeMethod("methodName", args) in proxy
Access static members
GetStaticField<T>(), GetStaticProperty<T>(), InvokeStaticMethod()
Properties
Target
object
public
The underlying proxied object instance
Extension Points
Implementation Pattern
To create a new proxy, subclass InternalProxy<TProxy> and decorate with [InternalProxy]:
1. Attribute
Apply [InternalProxy(typeof(TargetType))] or [InternalProxy("TypeName", "AssemblyName")]
2. Constructor
Accept object target and pass to base(target)
3. Members
Expose typed properties/methods using GetField, GetProperty, InvokeMethod
Implementation Requirements
When subclassing, you MUST:
Apply
[InternalProxyAttribute]specifying the target typeProvide a constructor accepting
object targetand forwarding tobase(target)
You SHOULD:
Expose internal members as strongly-typed public properties
Use descriptive property names that match the internal API semantics
Static Fields
type
Type
protected static readonly
The resolved target type from [InternalProxyAttribute]
Static Methods
Instance
Creates a new instance of the proxied internal type via Activator.CreateInstance.
parameters
object[]
Constructor arguments
Returns: A new instance of the target internal type.
Proxy
Wraps an existing object in a proxy instance. Returns null if target is null.
target
object
The internal object to wrap
Returns: A TProxy proxy wrapping the target.
GetProxyTargetType
Returns the System.Type of the proxied internal type.
Protected Instance Methods
GetField<TValue>
(string fieldName) → TValue
Gets an instance field value
SetField<TValue>
(string fieldName, TValue value)
Sets an instance field value
GetProperty<TValue>
(string propertyName) → TValue
Gets an instance property value
SetProperty<TValue>
(string propertyName, TValue value)
Sets an instance property value
InvokeMethod
(string methodName, params object[] parameters) → object
Invokes an instance method
Protected Static Methods
GetStaticField<TValue>
(string fieldName) → TValue
Gets a static field value
SetStaticField<TValue>
(string fieldName, TValue value)
Sets a static field value
GetStaticProperty<TValue>
(string propertyName) → TValue
Gets a static property value
SetStaticProperty<TValue>
(string propertyName, TValue value)
Sets a static property value
InvokeStaticMethod
(string methodName, params object[] parameters) → object
Invokes a static method
InternalProxyAttribute
Attribute that specifies the target internal type for an InternalProxy<TProxy> subclass.
Definition
Properties
Type
Type
public get
The resolved target internal type
Constructors
InternalProxyAttribute(Type type)
Specifies the target type directly
InternalProxyAttribute(string typeName, string assemblyName)
Resolves the type from name and assembly (throws if not found)
Common Pitfalls
Target type must exist If the target type specified in [InternalProxyAttribute] does not exist (e.g., removed in a Unity update), the static constructor will throw TypeLoadException at assembly load time.
Member name strings are not compile-time checked Field/property/method names are passed as strings. Typos or renamed internals will throw NullReferenceException when the cached lookup returns null.
TargetInvocationException unwrapping InvokeMethod unwraps TargetInvocationException and rethrows the InnerException. This means stack traces may not show the proxy call site.
Examples
Creating a Proxy for an Internal Unity Type
Using Assembly-Qualified Type Name
See Also
LowLevel Overview — subsystem overview
EditorHeaderItemInjector — uses similar reflection patterns
OnGUIInjector — uses similar reflection patterns
Last updated