Skip to content

Instantly share code, notes, and snippets.

@jeffijoe
Created June 24, 2015 07:08
Show Gist options
  • Save jeffijoe/d907bfff5f00cb7190fd to your computer and use it in GitHub Desktop.
Save jeffijoe/d907bfff5f00cb7190fd to your computer and use it in GitHub Desktop.
Utility I use in my tests to steal someone's private property.
// SkyClip
// - ReflectionHelper.cs
// --------------------------------------------------------------------
// Author: Jeff Hansen <jeff@jeffijoe.com>
// Copyright (C) Jeff Hansen 2015. All rights reserved.
using System;
using System.Reflection;
namespace SkyClip.TestHelpers.Reflection
{
/// <summary>
/// Reflection helper for tests.
/// </summary>
public static class ReflectionHelper
{
#region Public Methods and Operators
/// <summary>
/// Invokes the specified void method.
/// </summary>
/// <param name="obj">
/// The object.
/// </param>
/// <param name="voidMethodName">
/// Name of the void method.
/// </param>
/// <param name="parameters">
/// The parameters.
/// </param>
/// <exception cref="System.ArgumentException">
/// Method not found.
/// </exception>
public static void Invoke(this object obj, string voidMethodName, params object[] parameters)
{
var type = obj.GetType();
const BindingFlags BindingFlags = BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public
| BindingFlags.Instance;
var method = type.GetMethod(voidMethodName, BindingFlags);
if (method == null)
{
throw new ArgumentException(string.Format("Method not found: {0}", voidMethodName));
}
method.Invoke(obj, parameters);
}
/// <summary>
/// Invokes the specified returning method.
/// </summary>
/// <typeparam name="T">
/// Return type.
/// </typeparam>
/// <param name="obj">
/// The object.
/// </param>
/// <param name="returningMethodName">
/// Name of the returning method.
/// </param>
/// <param name="parameters">
/// The parameters.
/// </param>
/// <returns>
/// The return value of the method.
/// </returns>
/// <exception cref="System.ArgumentException">
/// Method not found.
/// </exception>
public static T Invoke<T>(this object obj, string returningMethodName, params object[] parameters)
{
var type = obj.GetType();
const BindingFlags BindingFlags = BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public
| BindingFlags.Instance;
var method = type.GetMethod(returningMethodName, BindingFlags);
if (method == null)
{
throw new ArgumentException(string.Format("Method not found: {0}", returningMethodName));
}
return (T)method.Invoke(obj, parameters);
}
/// <summary>
/// Sets the field.
/// </summary>
/// <param name="obj">
/// The object.
/// </param>
/// <param name="fieldName">
/// Name of the field.
/// </param>
/// <param name="value">
/// The value.
/// </param>
public static void SetFieldValue(this object obj, string fieldName, object value)
{
if (obj == null)
{
throw new ArgumentNullException("target", "The assignment target cannot be null.");
}
if (string.IsNullOrEmpty(fieldName))
{
throw new ArgumentException("fieldName", "The field name cannot be null or empty.");
}
Type t = obj.GetType();
FieldInfo fi = null;
while (t != null)
{
fi = t.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
if (fi != null)
{
break;
}
t = t.BaseType;
}
if (fi == null)
{
throw new Exception(string.Format("Field '{0}' not found in type hierarchy.", fieldName));
}
fi.SetValue(obj, value);
}
/// <summary>
/// Sets the property value.
/// </summary>
/// <param name="obj">
/// The object.
/// </param>
/// <param name="propertyName">
/// Name of the property.
/// </param>
/// <param name="value">
/// The value.
/// </param>
/// <exception cref="System.ArgumentException">
/// Property not found.
/// </exception>
public static void SetPropertyValue(this object obj, string propertyName, object value)
{
var type = obj.GetType();
const BindingFlags BindingFlags = BindingFlags.NonPublic | BindingFlags.Public
| BindingFlags.Instance | BindingFlags.Static;
var prop = type.GetProperty(
propertyName,
BindingFlags);
if (prop == null)
{
throw new ArgumentException(string.Format("Property not found: {0}", propertyName));
}
prop.SetValue(obj, value);
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment