C# 动态加载程序集

C# Loading assemblies dynamically

我在运行时将文本编译成动态对象时遇到问题。

我写了一段简单的代码编译文案:

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); ;
    }
}

这就是我使用 Compile 方法的方式。

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

如您所见,我在某些时候添加了对额外程序集的引用。出于某种原因,当我将 using System.Net; 添加到文本文件时,它不会被引用并且出现错误。我正在编译的文本实际上是一个保存为文本的 .cs 文件。我想通过提取 using * 并单独添加它们来解决这个问题,但是当添加 System.Net.Mail.dll 时,找不到元数据文件。

有没有人经历过类似的事情?我真的很想将 using * 添加到文件中并准备好。 任何输入将不胜感激。

这里的问题是 System.Net.dll 不存在。您可以通过右键单击它被引用的某处并选择 "Go to definition" 来检查 .Net 类型在哪个程序集中。这将打开一个带有 class 定义 "from metadata" 的选项卡。在此文件的顶部,您有一个 #region 显示此类型的来源。在 TcpClient 的情况下,我们可以看到:

#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

将您对 Compile 的调用更改为 "System.dll" 而不是 "System.Net.dll",它应该可以正常工作

Edit/Clarification: 无法从 using 语句中获取程序集名称。