Instantiating Classes through reflection using C# – Dynamic Object Creation

As I mentioned earlier, i’ve been working on a personal project in the few short hours I can steal each week.  Whilst I’m not ready to talk about the project itself, I did come across a particular situation I thought may be of interest.

The problem I had to solve was creating a class that would return a simple constant value.  It had to implement a certain interface however and, for various reasons, it wasn’t as simple as assigning the value to the class to return.  I needed to hard code the value into the class, but I needed to do it at runtime (so the value can be different for each instantiation.)  Basically, I needed to compile and create an instance of the object at run-time, with dynamically generated source code for the object itself.

Turns out, .Net 2.0 makes that quite easy.  Heres how it’s done:

How you generate your source-code is an issue all in itself, and was fairly simple in this case, but what you need is a string variable that contains the source code for the class you want to compile.  It needs to be complete as the system will compile it to an assembly.  An example is below:

string code =
    “using system;” +
    “namespace ExampleCode.Source {” +
    “public class helloWorld {” +
    “private string displayString; ” +
    “public helloWorld() {“
    “displayString = “Hello World!”; }” +
    “public string DisplayString() {” +
    “return displayString;}” +
     “}}”;

What you need then is the fully qualified type name of the class you want to instantiate.  In this case it’s going to be:

string typeName = “ExampleCode.Source.helloWorld”;

Compiling is a simple matter of calling the CompileAssemblyFromSource method of a CSharpCodeProvider.  A similar provider exists for VB.Net

CSharpCodeProvider compiler = new CSharpCodeProvider();

You need to pass in parameters however that visual studio normally takes care of for you, in particular the libraries to link to.

CompilerParameters compilerParams = new CompilerParameters(new string[] { “System.dll” });

The constructor parameters listed here is simply and array containing the name of every type you want to link to the assembly you are about to compile. System dlls and those of the current project can normally be added with a name only, for others you may need a full pathname.
CompilerParameters includes a lot of other functionality for controlling how the compilation project works, you may wish to check it out if you’re compiling something more complicated.

CompilerResults results = compiler.CompileAssemblyFromSource(compilerParams, new string[] { code });

All you need is a set of parameters and the code to compile and you’ve got an assembly.  The results returned contains a lot of information about how the compilation went and may contain a list of errors if the compile wasn’t successful.  You may have to output them and check while you’re first setting up to catch the little typos and logic errors that creep in to your dynamic code.  What it will also contain is the in-memory representation of the assembly itself. 

Getting your object instantiation now is easy:

object hw = results.CompiledAssembly.CreateInstance(typeName);

If everything has worked you’ve now got an instance of your dynamic class, just like all your design time compiled classes.  It’s an object only as your compiler knows nothing about it at runtime. You can get around this by having your class inherity from a base, or implement a known interface, and cast the object to one of these.

Hope this is helpful!

Advertisements

13 thoughts on “Instantiating Classes through reflection using C# – Dynamic Object Creation

  1. I believe this is exactly the tip I needed! I’m trying to make a dynamic wrapper that will turn very simple data objects with automatic properties into robust IEditableObjects with Undo/Redo and support for WinForms databinding. Combining this with generics may be the key I need. Thanks.

  2. Exactly how would I implement this though.

    I want to create a class based on a base class (methods predefined) using data from a database.

    In other words say I query tblTemplates for Templates and it returns 2 templates, and i query tblProperties for properties associated with these templates, I’d want to add to my base class

    public class Template1
    {
    public string property1 { get; set; }
    }
    public class Template2
    {
    public string property1 { get; set; }
    }

  3. System.Reflection.Emit contains a class called TypeBuilder that will let you build dynamic types. That will perform much better than this approach.

    This approach is great if you have a system that (for example) needs to allow technical users to add additional behaviours to the system by writing their own code, but if you as the developer are building/defining dynamic types, then the perfomance of this approach will be very very poor.

  4. Great idea but I need something simpler. I want to be able to create concrete instances of subclasses of abstract class but I do not know the
    names of concrete class before runtime. Meaning I will be able
    to obtain names at runtime only and I need to create a class from its name
    present in a string.

  5. I want my business entities to be built dynamically from the database. But I also need them to behave at design time like static objects. How can I do that?
    Can I build a control etc.? InitializeComponent() method of control will build the class assembly in memory. Will i be able to access that at design time? I have wasted a lot of time for finding solution of this problem but to no use. Please guide me. I will be thankful to you.

    Abbas

  6. NS – That’s correct, the original point of this example was to examine whether C# could be used as an in-program script.

    KV – The code you compile could easily be generated at runtime using the names of the classes. Or you could use Typebuilder which, as NS points out, has far greater performance.

    Abbas – I’m not really sure what you’re trying to do here… If you don’t know what the objects will be until runtime, how could you use them at design time? That seems like saying how can I drive my car to the store today, i’m buying it tomorrow.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s