I'm working on an application that's dynamically mapping requests to a variety of classes. Based on the inbound request a lookup into various meta data tables occurs and based on this string based look up data we decide which types to invoke. .NET makes it pretty easy to dynamically invoke types (and execute code) using Reflection, but finding the right methods for each of these approaches is not always so easy - there are a lot of different ways to arrive at the same operation.
So here's a quick summary of how to invoke types dynamically and a few type instantiation routines I have in my library.
The simplest way to invoke a type of course is to just instantiate it. You can simply use new() on any type and invoke it constructor. Behind the scenes .NET actually wires up instantiation code by finding the type and calling the appropriate constructor for the parameters you've passed and returns a type instance.
So a direct instantiation looks like this:
BaseSummaLpReport report = new SummaLpManager.Daily_Jrn_SampRpt();
Invoke through Constructor
So let's assume that you only have type information available, and you need to dynamically invoke the type. This may look a little silly without context because it's not all that often that you end up with a type and need to instantiate a class - a couple of common scenarios are add-ins and documentation generation. In the sample below I just provide the type for demonstration purposes.You know the assembly where the types live because the user registered an assembly or stored in a special location, and you use a marker interface or attributes to pick out the types that can work for an add-in for example. To invoke the add-in you have to dynamically load it because you don't know the concrete type name.
Constructor loading is fairly low level and somewhat verbose and it looks something like this:
BaseSummaLpReport report = typeof(SummaLpManager.Daily_Jrn_SumRpt).GetConstructor(Type.EmptyTypes).Invoke(null)
This is something akin to what .NET actually turns a new() instruction into - it's basically invoking the constructor. Using GetConstructor() can be pretty useful because you can cache constructors. If you end up repeatedly calling a dynamically invoked constructor caching the constructor instance can drastically improve invokation performance compared to dynamically looking up the constructor each time.
Constructor instantiation is pretty efficient but it can also get a little cumbersome because you have to find the exact parameter signature to call. Notice the call to GetConstructor with Type.EmptyTypes which basically is the no parameter version. If you have parameters, an array of types for each of the parameters must be passed.
Typed Instantiation with Activate.CreateInstance()
To make instantion a bit easier, there's the the static Activator class which provides a handy CreateInstance() method that can be invoked with a type. There's a plain parameter version and a generic version.
BaseSummaLpReport report = Activator.CreateInstance(typeof(SummaLpManager.Daily_Jrn_SumRpt))
This version supports a number of overloads (13 of them) and one of them allows for a list of parameters for activating specific constructors.
The generic version works similarly but it doesn't support any parameters.
BaseSummaLpReport report = Activator.CreateInstance<SummaLpManager.Daily_Jrn_SumRpt>();
One advantage of the generic version is that you don't need to explicitly do type conversion - the compiler automatically fixes up the type properly.
I would have thought the generic version would be faster and allow caching of the constructor potentially. However, running some quick perf tests, it looks like the non-generic version is actually significantly faster (not that it matters much - 10000 iterations registered around 8 milliseconds and 14 respectively).
Invoking by String
Finally you might also want to invoke an object just by its type name, which really comes back to the problem I mentioned above. In our app we have lookup tables in a database that match requests with specific class names. These tables are loaded on startup and classes are then invoked on the fly. There are two different sets: request handlers and report handlers. Both are based on the request's scriptname and translated.
There's no direct support for creating an instance of a type, but you can sort of get a type from a string by using Type.GetType(). It takes string parameter and returns a type from a fully qualified type name (namespace + type name). The following works:
If you look at the documentation for GetType() you'll find there's quite a bit of ambiguity and it really only works if you specify a fully qualified AssemblyQualifiedName which is useless in most dynamic scenarios. GetType() works with simple namespacae + typename only if the type exists in the current assembly or in mscorlib. Strike that as a generic routine.
So to get a type more reliably, albeit a lot more slowly is to write a small routine that walks the types of all loaded assemblies:
/// Helper routine that looks up a type name and tries to retrieve the
/// full type reference in the actively executing assemblies.
/// <param name="TypeName"></param>
public static Type GetTypeFromName(string TypeName)
Type type = Type.GetType(TypeName);
if (type != null)
// *** try to find manually
foreach (Assembly ass in AppDomain.CurrentDomain.GetAssemblies())
type = ass.GetType(TypeName, false);
if (type != null)
Once you have a type instance you can then use Activator.CreateInstance to instantiate it. To wrap this up as well you'd get a CreateInstance from string:
/// Creates an instance of a type based on a string. Assumes that the type's
/// <param name="typeName"></param>
/// <param name="args"></param>
public static object CreateInstanceFromString(string typeName, params object args)
object instance = null;
Type type = null;
type = GetTypeFromName(typeName);
if (type == null)
instance = Activator.CreateInstance(type, args);
catch (Exception ex)
COM Object Invokation
COM objects can also be invoked by first retrieving a .NET COM wrapper type from a ProgId with Type.CreateTypeFromProgId:
/// Creates a COM instance from a ProgID. Loads either
/// Exe or DLL servers.
/// <param name="progId"></param>
public static object CreateComInstance(string progId)
Type type = Type.GetTypeFromProgID(progId);
if (type == null)
It's interesting to compare the various different mechanisms. Obviously pure type instantiation is by far the fastest mechanism. In fact, I was running some very basic performance tests over the different mechanisms and as i did so with the direct instance results I got 0 milliseconds on the first few runs. I had to add some code to make sure the compiler wasn't just optimizing out dead code <s>, but sure enough, even with some dynamic assigment code times of objects without much state is extremely fast.
Creating instances using the CreateInstanceFromString method above on the other hand is a LOT slower. In fact for a custom type of mine in a Web app it took over 1000 times longer to run the same 10000 iterations. But keep in mind we're talking about 10000 iterations in about 1 second, so it's not like this will stop your app dead unless you run the string instantiation in a loop.
Instantiating an existing type is much faster by comparison - running only 30-40 times slower than raw instantiation. Relatively speaking that's a heck of a lot better.
If you do resort to string based instantiation frequently by creating lots of objects or creating them in a loop, consider caching either the type or even better the constructor. Storing reusable types in a Hashtable for reuse is an easy way to improve performance on repetive tasks as all the slow lookup code falls away. Most of the slowness in Reflection comes from doing type and member lookups and once you have the target member to invoke it's comparatively fast.
Dynamic invokation is not something you do every day - it's a specialty scenario but these days with so much meta programming and layers and layers of pluggable and adapter based code there's more and more of it around. Knowing how to get an instance is always nice.
For instance did I tell you the one about... nah, maybe another time...
Other Posts you might also like