|
//-------------------------------------------------------------------------------------
// <copyright file="ReflectionHelper.cs" company="Jonno">
// Copyright (c) 2009 Paul Johnson (paulmichael.johnson@gmail.com)
// Code is released under The Code Project Open License (CPOL).
// </copyright>
//-------------------------------------------------------------------------------------
namespace Jonno.Reflection
{
using System;
using System.Reflection;
using Jonno.Extensions;
/// <summary>
/// Runs methods in a class using reflection.
/// Can be used to run Private methods, or check private properties for testing purposes.
/// </summary>
/// <typeparam name="T">The type to work on.</typeparam>
/// <typeparam name="TResult">The type of any expected result.</typeparam>
public static class ReflectionHelper<T, TResult>
{
/// <summary>
/// The flags that control the reflection binding for instances.
/// </summary>
private const BindingFlags InstanceFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
/// <summary>
/// The flags that control the reflection binding for statics.
/// </summary>
private const BindingFlags StaticFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
/// <summary>
/// Gets a property value from an instance object using Reflection.
/// </summary>
/// <param name="property">The name of the property.</param>
/// <param name="instance">The instance object.</param>
/// <returns>The value of the property.</returns>
public static TResult GetInstanceProperty(string property, object instance)
{
return GetProperty(property, instance, InstanceFlags);
}
/// <summary>
/// Gets a static property value from a class using Reflection.
/// </summary>
/// <param name="property">The name of the property.</param>
/// <returns>The value of the property.</returns>
public static TResult GetStaticProperty(string property)
{
return GetProperty(property, null, StaticFlags);
}
/// <summary>
/// Gets a property value from an instance object using Reflection.
/// </summary>
/// <param name="property">The name of the property.</param>
/// <param name="instance">The instance object.</param>
/// <returns>The value of the property.</returns>
/// <param name="flags">The binding flags to use.</param>
public static TResult GetProperty(string property, object instance, BindingFlags flags)
{
var t = typeof(T);
var info = t.GetProperty(property, flags);
if (info == null || !info.CanRead)
{
ThrowArgumentException(property, t);
}
return (TResult)info.GetValue(instance, null);
}
/// <summary>
/// Gets a field value from an instance object using Reflection.
/// </summary>
/// <param name="member">The name of the field.</param>
/// <param name="instance">The instance object.</param>
/// <returns>The value of the field.</returns>
public static TResult GetInstanceField(string member, object instance)
{
return GetField(member, instance, InstanceFlags);
}
/// <summary>
/// Gets a static field value from a class using Reflection.
/// </summary>
/// <param name="member">The name of the field.</param>
/// <returns>The value of the field.</returns>
public static TResult GetStaticField(string member)
{
return GetField(member, null, StaticFlags);
}
/// <summary>
/// Gets a field value from an instance object using Reflection.
/// </summary>
/// <param name="member">The name of the field.</param>
/// <param name="instance">The instance object.</param>
/// <returns>The value of the field.</returns>
/// <param name="flags">The binding flags to use.</param>
public static TResult GetField(string member, object instance, BindingFlags flags)
{
var t = typeof(T);
var m = t.GetMember(member, flags);
FieldInfo f = null;
try
{
f = (FieldInfo)m[0];
}
catch
{
ThrowArgumentException(member, t);
}
return (TResult)f.GetValue(instance);
}
/// <summary>
/// Runs a method by using Reflection.
/// </summary>
/// <param name="method">The name of the method to call./</param>
/// <param name="instance">The instance object that will call the method.</param>
/// <param name="args">The methods arguments.</param>
/// <returns>The object that is returned by the method.</returns>
public static TResult RunInstanceMethod(string method, object instance, ref object[] args)
{
return RunMethod(method, instance, InstanceFlags, ref args);
}
/// <summary>
/// Runs a method by using Reflection.
/// </summary>
/// <param name="method">The name of the method to call./</param>
/// <param name="args">The methods arguments.</param>
/// <returns>The object that is returned by the method.</returns>
public static TResult RunStaticMethod(string method, ref object[] args)
{
return RunMethod(method, null, StaticFlags, ref args);
}
/// <summary>
/// Runs a method by using Reflection.
/// </summary>
/// <param name="method">The name of the method to call./</param>
/// <param name="instance">The instance object that will call the method.</param>
/// <param name="flags">The binding flags to use.</param>
/// <param name="args">The methods arguments.</param>
/// <returns>The object that is returned by the method.</returns>
public static TResult RunMethod(string method, object instance, BindingFlags flags, ref object[] args)
{
var t = typeof(T);
try
{
var m = t.GetMethod(method, flags);
if (m == null)
{
ThrowArgumentException(method, t);
}
return (TResult)m.Invoke(instance, args);
}
catch (TargetInvocationException ex)
{
if (ex.InnerException != null)
{
throw ex.InnerException;
}
else
{
throw ex;
}
}
catch
{
throw;
}
}
private static void ThrowArgumentException(string value, Type t)
{
throw new ArgumentException(string.Format("There is no '{0}' for type '{1}", value, t.ToString()));
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I have over 15 years of development experience, in many different languages, programming styles and platforms. Currently working as a C# coder, and residing in north Herts in the UK. I love lean software development and anything that reduces a grind to leave more time for useful coding!