Skip to content

Instantly share code, notes, and snippets.

@werwolfby
Created December 24, 2017 09:47
Show Gist options
  • Save werwolfby/d48382c33d5f7d189e278b20aa1f16e3 to your computer and use it in GitHub Desktop.
Save werwolfby/d48382c33d5f7d189e278b20aa1f16e3 to your computer and use it in GitHub Desktop.
Can be used in UnitTests to access private members over `dynamic` keyword.
public class AccessPrivateWrapper : DynamicObject
{
/// <summary>
/// The object we are going to wrap
/// </summary>
private readonly object _instance;
/// <summary>
/// Specify the flags for accessing members
/// </summary>
private const BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Instance
| BindingFlags.Static | BindingFlags.Public;
/// <summary>
/// Create a simple private wrapper
/// </summary>
public AccessPrivateWrapper(object instance)
{
this._instance = instance;
}
/// <summary>
/// Try invoking a method
/// </summary>
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
// TODO: Check if one of args is null
var types = args.Select(a => a.GetType()).ToArray();
var methodInfo = this._instance.GetType().GetMethod
(binder.Name, Flags, null, types, null);
if (methodInfo != null)
{
result = methodInfo.Invoke(this._instance, args);
return true;
}
return base.TryInvokeMember(binder, args, out result);
}
/// <summary>
/// Tries to get a property or field with the given name
/// </summary>
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
//Try getting a property of that name
var propertyInfo = this._instance.GetType().GetProperty(binder.Name, Flags);
if (propertyInfo != null)
{
result = propertyInfo.GetValue(this._instance, null);
return true;
}
//Try getting a field of that name
var fieldInfo = this._instance.GetType().GetField(binder.Name, Flags);
if (fieldInfo != null)
{
result = fieldInfo.GetValue(this._instance);
return true;
}
return base.TryGetMember(binder, out result);
}
/// <summary>
/// Tries to set a property or field with the given name
/// </summary>
public override bool TrySetMember(SetMemberBinder binder, object value)
{
var propertyInfo = this._instance.GetType().GetProperty(binder.Name, Flags);
if (propertyInfo != null)
{
propertyInfo.SetValue(this._instance, value, null);
return true;
}
var fieldInfo = this._instance.GetType().GetField(binder.Name, Flags);
if (fieldInfo != null)
{
fieldInfo.SetValue(this._instance, value);
return true;
}
return base.TrySetMember(binder, value);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment