Invoking a Generic Method With Parameters using Reflection





0/5 (0 vote)
Sample use of generics and type retrieval
Context
Imagine that you have few lookup tables[^]. Each one can have its own lookup method; e.g.,
string LookupCountryCodes(string query);
string LookupStateCodes(string query);
string LookupCardTypes(string query)
Likely, these methods differ only in the table /entity name that they apply to. Every time a new lookup table / entity is added, the lookup method has to be copied. Readability, extensibility, and maintainability of the code suffers.
Idea
Instead, we can define the lookup as a generic method[^]; e.g.,
string Lookup(string query) where T: class, ILookupEntity, new();
Then, given a table / entity name, we can find the associated:
- table / entity type
var t = Type.GetType(typeName);
if (t == null)
{
var types = from assembly in System.AppDomain.CurrentDomain.GetAssemblies()
from assemblyType in assembly.GetTypes()
where assemblyType.Name == typeName
select assemblyType;
t = types.FirstOrDefault();
}
- Lookup method
var method = [owner_of_lookup_method].GetType()
.GetMethod("Lookup", new Type[] {typeof (string)})
.MakeGenericMethod(entityType);
where the [owner_of_Lookup_method] is either a static class or an instance of an object with a Lookup method definition.
Implementation
Putting it all together:
private Dictionary<string,> typeCache = new Dictionary<string,>();
public bool TryFindType(string typeName, out Type t)
{
lock (typeCache)
{
if (!typeCache.TryGetValue(typeName, out t))
{
t = Type.GetType(typeName);
if (t == null)
{
var types = from assembly in System.AppDomain.CurrentDomain.GetAssemblies()
from assemblyType in assembly.GetTypes()
where assemblyType.Name == typeName
select assemblyType;
t = types.FirstOrDefault();
}
typeCache[typeName] = t; // perhaps null
}
}
return t != null;
}
public string Get(string entityTypeName, string query)
{
Type entityType;
if (TryFindType(entityTypeName, out entityType))
{
var method = [owner_of_lookup_method].GetType()
.GetMethod("Lookup", new Type[] {typeof (string)})
.MakeGenericMethod(entityType);
return Convert.ToString(method.Invoke([owner_of_lookup_method], new[] { query }));
}
return string.Empty;
}
See also:
How to use reflection to call generic method[^]
GetType returns null[^]
GetType returns null (2)[^]
How to invoke method with parameters[^]
Object does not match target type+Reflection[^]
Overcoming problems with MethodInfo.Invoke of methods with by-reference value type arguments[^]