Skip to content

Commit

Permalink
Add reflection docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Limiana committed Mar 26, 2024
1 parent 18a9ad7 commit 6c6e6db
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 9 deletions.
30 changes: 28 additions & 2 deletions ECommons/Reflection/ReflectionHelper/Call.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,26 @@ namespace ECommons.Reflection;
#nullable disable
public static partial class ReflectionHelper
{
public static object Call(this object obj, string methodName, IEnumerable<string> methodTypeArguments, object[] parameters) => Call(obj, [obj.GetType().Assembly], methodName, methodTypeArguments, parameters);
/// <summary>
/// Calls a generic or non-generic method of an instance.
/// </summary>
/// <param name="instance">Instance containing method</param>
/// <param name="methodName">Name of a method to call.</param>
/// <param name="methodTypeArguments">Generic argument names. Pass empty array or null if a function is non-generic. Generic types only will be searched within <paramref name="instance"/> assembly.</param>
/// <param name="parameters">Parameters to call method with.</param>
/// <returns>Object returned by a method.</returns>
public static object Call(this object instance, string methodName, IEnumerable<string> methodTypeArguments, object[] parameters) => Call(instance, [instance.GetType().Assembly], methodName, methodTypeArguments, parameters);

public static object Call(this object obj, IEnumerable<Assembly> assemblies, string methodName, IEnumerable<string> methodTypeArguments, object[] parameters)
/// <summary>
/// Calls a generic or non-generic method of an instance.
/// </summary>
/// <param name="obj">Instance containing method</param>
/// <param name="assemblies">Assemblies to search types in. Only required if <paramref name="methodTypeArguments"/> is used.</param>
/// <param name="methodName">Name of a method to call.</param>
/// <param name="methodTypeArguments">Generic argument names. Pass empty array or null if a function is non-generic, otherwise also populate <paramref name="assemblies"/> parameter.</param>
/// <param name="parameters">Parameters to call method with.</param>
/// <returns>Object returned by a method.</returns>
public static object Call(this object obj, IEnumerable<Assembly>? assemblies, string methodName, IEnumerable<string>? methodTypeArguments, object[] parameters)
{
var methodInfo = obj.GetType().GetMethod(methodName, AllFlags, parameters.Select(x => x.GetType()).ToArray());
if (methodInfo != null)
Expand All @@ -31,5 +48,14 @@ public static object Call(this object obj, IEnumerable<Assembly> assemblies, str
return methodInfo?.Invoke(obj, parameters);
}

/// <summary>
/// Calls a generic or non-generic method of an instance.
/// </summary>
/// <param name="obj">Instance containing method</param>
/// <param name="assemblies">Assemblies to search types in. Only required if <paramref name="methodTypeArguments"/> is used.</param>
/// <param name="methodName">Name of a method to call.</param>
/// <param name="methodTypeArguments">Generic argument names. Pass empty array or null if a function is non-generic, otherwise also populate <paramref name="assemblies"/> parameter.</param>
/// <param name="parameters">Parameters to call method with.</param>
/// <returns>Object returned by a method.</returns>
public static T Call<T>(this object obj, IEnumerable<Assembly> assemblies, string methodName, IEnumerable<string> methodTypeArguments, object[] parameters) => (T)Call(obj, assemblies, methodName, methodTypeArguments, parameters);
}
44 changes: 39 additions & 5 deletions ECommons/Reflection/ReflectionHelper/ReflectionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,35 @@ public static partial class ReflectionHelper
public const BindingFlags StaticFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
public const BindingFlags InstanceFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;

/// <summary>
/// Gets field or property of an instance object.
/// </summary>
/// <param name="obj">Instance containing field/property.</param>
/// <param name="name">Name of the field/property</param>
/// <returns>Value of a field/property</returns>
public static object GetFoP(this object obj, string name)
{
return obj.GetType().GetField(name, AllFlags)?.GetValue(obj)
?? obj.GetType().GetProperty(name, AllFlags)?.GetValue(obj);
}

/// <summary>
/// Gets field or property of an instance object.
/// </summary>
/// <param name="obj">Instance containing field/property.</param>
/// <param name="name">Name of the field/property</param>
/// <returns>Value of a field/property</returns>
public static T GetFoP<T>(this object obj, string name)
{
return (T)GetFoP(obj, name);
}

/// <summary>
/// Sets a field or property of an instance object.
/// </summary>
/// <param name="obj">Instance containing field/property.</param>
/// <param name="name">Name of the field/property</param>
/// <param name="value">Value to set</param>
public static void SetFoP(this object obj, string name, object value)
{
var field = obj.GetType().GetField(name, AllFlags);
Expand Down Expand Up @@ -75,7 +93,15 @@ public static void SetStaticFoP(this object obj, string type, string name, objec
}
}

public static object Call(this object obj, string name, object[] values, bool matchExactArgumentTypes = false)
/// <summary>
/// Attempts to call a non-generic instance method.
/// </summary>
/// <param name="obj">Instance containing method</param>
/// <param name="name">Method's name</param>
/// <param name="params">Method's parameters</param>
/// <param name="matchExactArgumentTypes">Whether to search for exact method types. Set this to true if you're dealing with ambiguous overloads.</param>
/// <returns>Object returned by the target method</returns>
public static object Call(this object obj, string name, object[] @params, bool matchExactArgumentTypes = false)
{
MethodInfo info;
if (!matchExactArgumentTypes)
Expand All @@ -84,13 +110,21 @@ public static object Call(this object obj, string name, object[] values, bool ma
}
else
{
info = obj.GetType().GetMethod(name, AllFlags, values.Select(x => x.GetType()).ToArray());
info = obj.GetType().GetMethod(name, AllFlags, @params.Select(x => x.GetType()).ToArray());
}
return info.Invoke(obj, values);
return info.Invoke(obj, @params);
}

public static T Call<T>(this object obj, string name, object[] values, bool matchExactArgumentTypes = false)
/// <summary>
/// Attempts to call a non-generic instance method.
/// </summary>
/// <param name="obj">Instance containing method</param>
/// <param name="name">Method's name</param>
/// <param name="params">Method's parameters</param>
/// <param name="matchExactArgumentTypes">Whether to search for exact method types. Set this to true if you're dealing with ambiguous overloads.</param>
/// <returns>Object returned by the target method</returns>
public static T Call<T>(this object obj, string name, object[] @params, bool matchExactArgumentTypes = false)
{
return (T)Call(obj, name, values, matchExactArgumentTypes);
return (T)Call(obj, name, @params, matchExactArgumentTypes);
}
}
15 changes: 13 additions & 2 deletions ECommons/Reflection/ReflectionHelper/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public static MethodInfo FindStaticMethodInAssemblies(IEnumerable<Assembly> asse
}

/// <summary>
/// Searches for specified types in specified assembly list.
/// Searches for specified non-generic types in specified assembly list.
/// </summary>
/// <param name="assemblies">Assemblies to search in</param>
/// <param name="typeNames">A list of requested types names</param>
Expand All @@ -77,7 +77,12 @@ public static List<Type> FindTypesInAssemblies(IEnumerable<Assembly> assemblies,
return genericArgs;
}


/// <summary>
/// Searches for specified generic and non-generic types in specified assembly list.
/// </summary>
/// <param name="assemblies">Assemblies to search in</param>
/// <param name="typeNames">A list of tuples of requested types names and generic argument types. Array of types can be left empty or null to specify that this type is non-generic.</param>
/// <returns>A list of requested types. Please check resulting list length to ensure all types were found.</returns>
public static List<Type> FindTypesInAssemblies(IEnumerable<Assembly> assemblies, IEnumerable<(string TypeName, Type[] TypeArguments)> typeNames)
{
var genericArgs = new List<Type>();
Expand Down Expand Up @@ -121,6 +126,12 @@ public static Type[] GetTypes(this IEnumerable<object> objects)
return objects.Select(x => x.GetType()).ToArray();
}

/// <summary>
/// Creates delegate to a method by MethodInfo
/// </summary>
/// <param name="methodInfo">MethodInfo of a method for which a delegate will be created.</param>
/// <param name="target">Instance object that is hosting the method. Pass null if a method is static.</param>
/// <returns></returns>
public static Delegate CreateDelegate(MethodInfo methodInfo, object target)
{
Func<Type[], Type> getType;
Expand Down

0 comments on commit 6c6e6db

Please sign in to comment.