Compilation et appel de code C# dans un System.String au runtime

Voici un petit bout de code vous permettant de compiler du code sous forme de string et d’instancier des objets. Pour éviter d’écrire du code d’appel par réflexion, ma classe a générer implémente une interface que j’utiliserai ensuite manipuler le resultant de CreateObjectFromAssembly. Seul la construction de l’objet se fait par réflexion.

/// <summary>
/// Produces new assembly at runtime.
/// </summary>
/// <param name="references">The assembly references.</param>
/// <param name="sourceCode">The source code to compile.</param>
/// <param name="outputAssemblyName">Output dll name.</param>
/// <returns>Compilation result</returns>
private CompilerResults ProduceAssembly(string[] references, 
                                        string sourceCode, 
                                        string outputAssemblyName)
{
    CSharpCodeProvider codeProvider = new CSharpCodeProvider();
    ICodeCompiler codeCompiler = codeProvider.CreateCompiler();

    CompilerParameters compilerParameters = 
                    new CompilerParameters(references, 
                                            outputAssemblyName);
    compilerParameters.GenerateExecutable = false;
    compilerParameters.GenerateInMemory = false;

    return codeCompiler.CompileAssemblyFromSource(compilerParameters, 
                                                  sourceCode);

}

/// <summary>
/// Creates new object from dynamicaly loaded assembly
/// </summary>
/// <param name="AssemblyName">Name of the assembly to load.</param>
/// <param name="className">Name of the class to instanciate.</param>
/// <param name="constructorParameters">The constructor parameters.</param>
private bool CreateObjectFromAssembly(string AssemblyName, 
                                        string className, 
                                        object[] constructorParameters, 
                                        out object createdObject)
{
    object tmp = createdObject = null;
    Assembly myAssembly = Assembly.LoadFrom(AssemblyName);
    Module[] myModules = myAssembly.GetModules();

    myModules.Where(module => module.Name == AssemblyName)
             .Select(module => module.GetTypes())
             .ToList()
             .ForEach
             (
             t => t.Where(types => types.Name == className)
                   .ToList()
                   .ForEach(
                          type => tmp = Activator.CreateInstance(type, 
                                               constructorParameters))
             );
    createdObject = tmp;
    return createdObject != null;
}

Pastebin : http://pastebin.com/S6fpYcXD

Published by Emmanuel Istace

Musician, Software developer and guitar instructor. https://emmanuelistace.be/

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 )

Connecting to %s

%d bloggers like this: