Click here to Skip to main content
15,881,248 members
Articles / Programming Languages / C# 4.0
Tip/Trick

Dynamic Compilation and Loading of .NET Objects

Rate me:
Please Sign up or sign in to vote.
4.67/5 (4 votes)
9 Apr 2015CPOL2 min read 20.6K   20   12
This is another approach to dynamic compilation of objects and their usage via Interfaces.

Introduction

When I read about dynamic compilation in .NET (which is a great feature) for the first time, I soon got stuck with the samples I found. Mostly, they covered the idea of writing small functions dynamically as we can find on various web pages with tutorials. These samples discuss problems like speed of execution or different ways to access the compiled function. But I wanted more. My idea was: I want to compile and use an whole object (or even some more) with members and methods without taking too much care about reflection (yes, some reflection is necessary, I know).

Using the Code

Basically, our best friends here are Microsoft.CSharp and System.CodeDom.Compiler. But to make this simple magic of having an instance of the dynamically compiled object, we also use a simple interface like this:

C#
using System; 
namespace Iface {
     public interface ImyInterface
     {
         string text {get; set;}
         int number {get; set;}
         int Func (int a, int b);
     } 
}

To make this interface available to the dynamically compiled code, I put this interface into a calls library, called "Iface.dll".

For the basic program, I add a reference to the Iface.dll and add the namespace together with all others necessary for this example:

C#
using System;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Text;
using Iface;

The code for the dynamically compiled object is as follows:

C#
const string code=@"
    using System;
    namespace TestClass
    {
        public class MyClass : Iface.ImyInterface
        {
            public int i;
            public string text {get; set;}
            public int number {get; set;}
            public int Func (int a, int b){
                i=a+b;
                return a+b;
            }
        }
    }
";

As you can see, it's just an implementation of the interface doing nothing special.

For the compilation at runtime, we need a CSharpCodeProvider and CompilerParameters:

C#
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();    
parameters.ReferencedAssemblies.Add("Iface.dll");        
parameters.GenerateInMemory = true;           

Please note: When the program is compiled, a copy of the "Iface.dll" is placed in the same directory as the executable. So, the path for the referenced assembly is limited to "Iface.dll".

Next step: Compilation and some error handling.

C#
CompilerResults results = provider.CompileAssemblyFromSource(parameters, code);

if (results.Errors.HasErrors)
{
    StringBuilder sb = new StringBuilder();        
    foreach (CompilerError error in results.Errors)
    {
        sb.AppendLine(String.Format("Error ({0}): {1}", error.ErrorNumber, error.ErrorText));
    }            
    throw new InvalidOperationException(sb.ToString());
}

And finally we get our object:

C#
Assembly assembly = results.CompiledAssembly;
Type asmType = assembly.GetType("TestClass.MyClass");
Type[] argTypes=new Type[] { };
ConstructorInfo cInfo=asmType.GetConstructor(argTypes);
ImyInterface myclass=(ImyInterface)cInfo.Invoke(null);

int result=myclass.Func(1,2);        
Console.WriteLine("and the result is: {0}",result);
Console.ReadKey(true);

Points of Interest

This is my very first post on CodeProject. So I'll appreciate any comments about this work. Maybe, there are much easier ways to achieve what I tried to do and if you know one, please tell me.

History

  • 9th April, 2015: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader
Germany Germany
I'm a Team Leader of a small development team dealing mainly with embedded software. C# and .Net is just a hobby to me.

Comments and Discussions

 
GeneralDynamic compiler Pin
bariq qadri10-Apr-15 20:42
bariq qadri10-Apr-15 20:42 
GeneralRe: Dynamic compiler Pin
Florian Braun10-Apr-15 21:38
professionalFlorian Braun10-Apr-15 21:38 
GeneralRe: Dynamic compiler Pin
bariq qadri10-Apr-15 21:50
bariq qadri10-Apr-15 21:50 
GeneralRe: Dynamic compiler Pin
Florian Braun10-Apr-15 22:05
professionalFlorian Braun10-Apr-15 22:05 
QuestionWhy would I use it?? Pin
shrknt3510-Apr-15 1:21
shrknt3510-Apr-15 1:21 
QuestionWhy would I use it?? Pin
shrknt3510-Apr-15 1:21
shrknt3510-Apr-15 1:21 
AnswerRe: Why would I use it?? Pin
Florian Braun10-Apr-15 1:59
professionalFlorian Braun10-Apr-15 1:59 
GeneralRe: Why would I use it?? Pin
shrknt3510-Apr-15 2:39
shrknt3510-Apr-15 2:39 
AnswerRe: Why would I use it?? Pin
BManfred14-Apr-15 0:55
BManfred14-Apr-15 0:55 
QuestionIt is a great topic Pin
Oleg Shilo9-Apr-15 14:36
Oleg Shilo9-Apr-15 14:36 
AnswerRe: It is a great topic Pin
sapatag9-Apr-15 22:39
sapatag9-Apr-15 22:39 
GeneralRe: It is a great topic Pin
Oleg Shilo10-Apr-15 1:28
Oleg Shilo10-Apr-15 1:28 
It is http://csscript.net/[^]

Or on CodePLex: https://csscriptsource.codeplex.com/[^]

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.