简体   繁体   中英

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM