Dynamically Generate A Class From An Interface Part 2

By Anthony Jackson. Filed in C#  |  
TOP del.icio.us digg

In Part 1 of Dynamically Generate A Class From An Interface, we started work on being able to compose objects for use in Dependency Injection as part of an overall dynamic system.  We discussed being able to take any Interface definition consisting only of properties and turn it into source code.  In this post, we’ll discuss turning the source code created by the method in Part 1 into a compiled class with an instantiated object being returned.

So let’s get started on a method which compiles the source code, instantiates an object of the given type and returns it to the caller.

Like the prior method, we’ll be using a generic type parameter to pass the Interface we’re working with and that we expect the returned object to implement, along with the ClassSourceCode object that contains the source code we intend to compile.  Of course, we’ll also declare a return object to hold the instantiated class which implements the passed in Interface.



public T Create<T>(ClassSourceCode classSourceCode)

{

T returnObject;


The CSharpCodeProvider class provided by the .Net framework makes it easy to compile code.  This is not a class that we can instantiate directly with new.  Instead we use the Factory method provided by the CodeDomProvider to create and return an instance of the class.  In this case, we’re specifying V4.0 of the .Net framework.  Keep in mind that most articles on the topic show an outdated method for compiling code which was the preferred method in older versions of the framework but is now obsolete.  The methods we’re using are the currently supported way of doing it at least as of Framework 4.0 and the writing of this article.



CSharpCodeProvider csharpCodeProvider =

(CSharpCodeProvider)CodeDomProvider.CreateProvider(

"C#",new Dictionary<string, string>{{"CompilerVersion","v4.0"}});


Next we create a CompilerParameters object and set a few of the parameters we’ll be using.  As we’re going to compile and immediately instantiate an object, we’re not looking for an executable or even a dll to be created.  We’re simply going to have it live in memory only.

We’ll also add the assembly that contains the passed in Interface as a referenced assembly.  If you take a look back in Part 1, you’ll see that the class we’re creating implements the Interface.  Our assumption is that this interface exists within the calling assembly; if this is not the case, you’ll need to modify the code to set a reference some other way.



CompilerParameters compilerParameters = new CompilerParameters();

compilerParameters.GenerateInMemory = true;

compilerParameters.GenerateExecutable = false;

compilerParameters.ReferencedAssemblies.Add(typeof(T).Assembly.Location);


Compiling the source code is just a simple matter of asking the code provider to do so with the parameters and source code.  The interesting piece is if errors are returned.  To keep things simple, we’re simply throwing an exception containing the very first error.  If you’re using this extensively, you may want to build a little more functionality around this piece.  Possibly even separate out compilation from instantiation to allow for creation of a UI to work with code in if you’re using this for more than just the scenario outlined in these articles.



CompilerResults compilerResults = csharpCodeProvider.CompileAssemblyFromSource(compilerParameters, classSourceCode.SourceCode);

if (compilerResults.Errors.HasErrors)

{

throw new Exception(compilerResults.Errors[0].ErrorText);

}


All we have left to do now is to use the compiler results to actually create an instance of the object and return it.  You now have not only a compiled class, but an actual object that you can manipulate in the calling code.



returnObject = (T)compilerResults.CompiledAssembly.CreateInstance(typeof(T).Namespace + "." + classSourceCode.ClassName);

return returnObject;

}

While this is a great start and took us through an interesting use of reflection and runtime code compilation; we’re still a little short on being able to use this for much.  This object has properties but doesn’t have the capability of doing anything real.  In a future article, we’ll discuss modifying the class that is created to inherit from a class that automatically will give the object basic database CRUD (create, read, update, delete) operations using reflection and no additional coding necessary.  But first, before we get to far we need to make certain that the code we’ve written works.

Dynamically Generate A Class From An Interface Part 3 Unit Tests

In the next article, we’ll create a unit test for each method using MSTest and make sure that we’re getting the results we want.

About Anthony Jackson

Anthony Jackson has written 10 posts in this blog.

Anthony has been developing software professionally since 1996; working primarily with Microsoft technologies such as C#, VB.NET, ASP.NET and MS SQL Server. He has a varied background working in a number of industries, on teams of different sizes including Enterprise Application Development. He often takes on varied roles for projects as well, quickly adapting to what is needed for a given project and is involved in the full life-cycle of software development. This blog and it's articles are entirely the opinion of the author Anthony Jackson and do not reflect the opinions of his employers or clients past, present or future. He currently works for Avanade as a Senior System Analyst and loves working their, but everything written is still just his opinion and does not necessary reflect on any of his employers or clients past, present or future.

One comment to “Dynamically Generate A Class From An Interface Part 2”

TrackBacks / PingBacks

  1. Pingback
    Dynamically Generate A Class From An Interface Part 1 » Anthony Jackson's Software Development Blog

Leave a Reply

You must be logged in to post a comment.