Robinnaiitor
Robinnaiitor

Reputation: 119

C# Loading assemblies dynamically

I'm having an issue when compiling text into dynamic objects at runtime.

I wrote a simple piece of code to compile the text:

public class CompileFactory
{
    public dynamic Compile(String classCode, String mainClass, Object[] requiredAssemblies)
    {
        CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string> 
          { 
             { "CompilerVersion", "v4.0" } 
          });

        CompilerParameters parameters = new CompilerParameters
        {
            GenerateExecutable = true,       // Create a dll
            GenerateInMemory = true,          // Create it in memory
            WarningLevel = 3,                 // Default warning level
            CompilerOptions = "/optimize",    // Optimize code
            TreatWarningsAsErrors = false     // Better be false to avoid break in warnings
        };

        // Add all extra assemblies required
        foreach (var extraAsm in requiredAssemblies)
        {
            parameters.ReferencedAssemblies.Add(extraAsm as string);
        }
        CompilerResults results = provider.CompileAssemblyFromSource(parameters, classCode);
        if (results.Errors.Count != 0)
        {
            return "FAILED";
        }
        return results.CompiledAssembly.CreateInstance(mainClass); ;
    }
}

This is how I am using the Compile method.

List<string> assemblies = new List<string>{"System.Net.Mail.dll", "System.Net.dll"};
dynamic obj = compile.Compile(fileText, pluginName, assemblies.ToArray()); 

As you can see I'm adding references to extra assemblies at some point. For some reason when I add using System.Net; to the text file, it will not be referenced and I get errors. The text I'm compiling is literally a .cs file saved as text. I thought of working around this by extracting the using * and adding them separately, however for when adding System.Net.Mail.dll, the metadata file cannot be found.

Has anyone experienced something similar? I really would like to just add the using * to the file and be ready with it. Any input would be greatly appreciated.

Upvotes: 3

Views: 1590

Answers (1)

Philippe Par&#233;
Philippe Par&#233;

Reputation: 4418

The issue here is that System.Net.dll does not exist. You can check in which assembly a .Net type is by right clicking somewhere it is referenced and choosing "Go to definition". This will bring up a tab with the class definition "from metadata". At the top of this file, you've got a #region showing where this type comes from. In the case of a TcpClient, we can see this:

#region Assembly System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.dll
#endregion

Change your call to Compile with "System.dll" instead of "System.Net.dll" and it should work just fine

Edit/Clarification: It is not possible to get an assembly name from a using statement.

Upvotes: 2

Related Questions