Dynamic compilation is an awesome feature to add to your projects. Especially frameworks will benefit from the compilation of dynamic expressions and scripts. There are two main ways of doing it: the Code DOM Compiler and the Roslyn project. I’ll show how to implement them both.

Dynamic code compilation

We are going to compile a string into a DLL, so we need that string to contain a class. In order to interact with the compiled object we’ll need to define an interface (I guess it could be done with reflection, but that makes things unnecessary complicated).

There are basically 2 kinds of expressions; those that generate a result and those that don’t (scripts). By creating two interfaces for these types of behaviors we allow the end user to implement them.

You can define your own interface. These interfaces will be used by the extension methods that I’ll build on top to the compiler interface later.

Compiler abstraction

Let’s define an abstraction of a compiler: the ICompiler interface. The idea is that an ICompiler builds the code into an new assembly. In order to build code you’ll need to give it the paths of the DLL’s you are referencing in your code.

Code DOM Compiler implementation

The main way of doing compilation is the .Net Code DOM Compiler. It can be used by adding a reference to the Microsoft.CSharp DLL. Let’s take a look at the implementation:

It is pretty straight forward. You might want to change the parameters.GenerateInMemory = true; for bigger projects and use a file based caching mechanism. I’ll show how to implement caching later.

Roslyn Compiler implementation

The .Net team has been very busy building a new managed compiler for C#:

The .NET Compiler Platform (“Roslyn”) provides open-source C# and Visual Basic compilers with rich code analysis APIs. You can build code analysis tools with the same APIs that Microsoft is using to implement Visual Studio!

First install the Roslyn NuGet package:

Install-Package Microsoft.CodeAnalysis -Pre»

Let’s inspect the ICompiler implementation:

Remember: the Roslyn project is still in beta! You might want to use an IoC mechanism in your projects to resolve the compiler implementation.

Cached result compiler

Now we’ve got two compilers, let’s create a memory cached version using a ConcurrentDictionary.

You might want to research a better way of locking by adding named locks.

Extension methods

Let’s use extension methods to help build and retrieve results. First we’ll make a settings object with all the instructions. It’s a nice little container that will bundle the assembly locations, the code and the name of the class together. Especially the name is important, because it will be used to run the class.

So let’s inspect the extension methods:

  • CompileAndCreateObject – compiles the code and returns the class that was specified as the class name.
  • CompileAndCreateObject<T> – same method, but it will do the casting for you
  • RunScript – will assume your code class implements an IScrip. It will compile and run the script.
  • RunProducer – will assume your code class implements an IProducer. It will compile and run the code and return the result.

Hello world!

Now let’s build a Hello World application using all the compilers we’ve created:

So that’s it. Let me know if you are going to use it in any of your projects. Have fun!