This is my ReflectionWrapper which you can construct on an instance of an object, a type etc and will let you call public and private methods. I use it mostly to wrap things that aren’t supposed to be exposed by Unity.
It can do things like setting/getting a sub property whatever. It’s got generics to cast the type more easily:
var wrapper = new ReflectionWrapper(someObject);
int i = wrapper.GetValue<int>("somePropertyOrField");
string j = wrapper.GetValue<string>("someObjectFieldOrProperty.someStringProperty");
wrapper.SetValue("someOtherObjectFieldOrProperty.someString", j);
wrapper.Call("SomeMethod");
int = wrapper.Call<int>("SomeFunction");
You can also wrap an object by just knowing its type name and assembly then call ConstructInstance:
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System.Collections;
using System;
using System.Reflection;
using System.Linq;
public class ReflectionWrapper
{
public Type baseType;
public object instance;
public ReflectionWrapper(string assemblyName, string typeName)
{
var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a=> { return a.GetName().Name == assemblyName; });
baseType = assembly.GetType (assemblyName + "." + typeName);
if(baseType == null)
baseType = assembly.GetType (typeName);
}//
public ReflectionWrapper(Assembly assembly, string typeName)
{
baseType = assembly.GetType (typeName);
}
public ReflectionWrapper(object instance)
{
baseType = instance.GetType();
this.instance = instance;
}
public object this[string path]
{
get
{
return GetValue(path);
}
set
{
SetValue (path, value);
}
}
public object GetValue (string path)
{
var pathParts = path.Split('.');
var currentObject = instance;//
for(var i = 0; i < pathParts.Length; i++)
{
var f = currentObject.GetType().GetField(pathParts*, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);*
_ var p = currentObject.GetType().GetProperty(pathParts*, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);_
_ if(p == null)_
_ throw new Exception("Property not found: " + pathParts);
currentObject = p.GetValue(currentObject, null);
}*_
* }*
* return currentObject;*
* }*
* public void SetValue (string path, object value)*
* {*
* var pathParts = path.Split(‘.’);*
* var currentObject = instance;//*
* for(var i = 0; i < pathParts.Length-1; i++)*
* {*
_ var f = currentObject.GetType().GetField(pathParts*, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if(f != null)
{
currentObject = f.GetValue(currentObject);
}
else*
* {
var p = currentObject.GetType().GetProperty(pathParts, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if(p == null)
throw new Exception("Property not found: " + pathParts);
currentObject = p.GetValue(currentObject, null);
}*_
* }*
* //Set the last part*
* {*
_ var f = currentObject.GetType().GetField(pathParts*, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if(f != null)
{
f.SetValue(currentObject, value);
}
else*
* {
var p = currentObject.GetType().GetProperty(pathParts, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if(p == null)
throw new Exception("Property not found: " + pathParts);
p.SetValue (currentObject, value, null);
}
}
}*_
* public T GetValue(string path)*
* {*
* return (T)GetValue (path);*
* }*
* protected void ConstructInstance(Type [] types, params object[] parameters)*
* {*
* var constructor = baseType.GetConstructor (types);*
* instance = constructor.Invoke (parameters);*
* }*
* protected void ConstructInstance(params object[] parameters)*
* {*
* var constructor = baseType.GetConstructor (parameters.Select (p => p.GetType ()).ToArray ());*
* instance = constructor.Invoke (parameters);*
* }*
* public T GetProperty(string name)*
* {*
* return (T)GetProperty (name);*
* }*
* public T GetField(string name)*
* {*
* return (T)GetField (name);*
* }*
* public T Call(string name, params object[] parameters)*
* {*
* return (T)Call (name, parameters) ;*
* }*
* public object GetProperty(string name)*
* {*
* return baseType.GetProperty (name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).GetValue (instance, null);*
* }*
* public void SetProperty(string name, object value)*
* {*
* baseType.GetProperty (name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue (instance, value, null);*
* }*
* public object GetField(string name)*
* {*
* return baseType.GetField (name, BindingFlags.Public | BindingFlags.NonPublic| BindingFlags.Instance).GetValue (instance);*
* }*
* public void SetField(string name, object value)*
* {*
* baseType.GetField (name, BindingFlags.Public | BindingFlags.NonPublic| BindingFlags.Instance).SetValue (instance, value);*
* }*
* public object Call(string name, params object[] parameters)*
* {*
* var method = baseType.GetMethods (*
* BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)*
* .FirstOrDefault (m => {*
* if(m.Name != name) return false;*
* var parms = m.GetParameters();//*
* for(var i = 0; i < parms.Length; i++)*
* {*
_ if(i >= parameters.Length && !parms*.IsOptional)
return false;
if(i < parameters.Length && !parms.ParameterType.IsAssignableFrom(parameters.GetType()))
return false;
}*_
* return true;*
* });*
* return method.Invoke (instance, parameters );*
* }*
* public object CallStatic(string name, params object[] parameters)*
* {*
* var method = baseType.GetMethods (*
* BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)*
* .FirstOrDefault (m => {*
* if(m.Name != name) return false;*
* var parms = m.GetParameters();//*
* for(var i = 0; i < parms.Length; i++)*
* {*
_ if(i >= parameters.Length && !parms*.IsOptional)
return false;
if(i < parameters.Length && !parms.ParameterType.IsAssignableFrom(parameters.GetType()))
return false;
}*_
* return true;*
* });*
* return method.Invoke (null, parameters );*
* }*
* public void SetDelegate(string name, Delegate del)*
* {*
* var field = baseType.GetField (*
* name,*
* BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase);*
* if (field != null)*
* {*
* field.SetValue (instance, Delegate.CreateDelegate (field.FieldType, del.Target, del.Method));*
* }*
* else*
* {*
* var property = baseType.GetProperty(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase);*
* property.SetValue (instance, Delegate.CreateDelegate (property.PropertyType, del.Target, del.Method), null);*
* }*
* }*
}