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<t>(string query) where T: class, ILookupEntity, new();
</t>
Then, given a table / entity name, we can find the associated:
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();
}
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;
}
}
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[
^]