编译器参数.引用程序集--添加对System.Web.UI.WebControls的引用

9

我正在使用CodeDomProvider类在运行时编译类。这对于仅使用System命名空间的类有效:

using System;

public class Test
{
    public String HelloWorld()
    {
        return "Hello World!";
    }
}

如果我尝试编译一个使用 System.Web.UI.WebControls 的类,我会得到以下错误信息:

{error CS0006: 找不到元数据文件 'System.Web.UI.WebControls'} System.CodeDom.Compiler.CompilerError

以下是我的代码片段:
var cp = new CompilerParameters();

cp.ReferencedAssemblies.Add("System.Web.UI.WebControls");

我该如何引用 System.Web.UI.WebControls 命名空间?

3个回答

44
您可以循环遍历所有当前加载的程序集:
var assemblies = AppDomain.CurrentDomain
                            .GetAssemblies()
                            .Where(a => !a.IsDynamic)
                            .Select(a => a.Location);   

cp.ReferencedAssemblies.AddRange(assemblies.ToArray());

为什么要使用try/catch,而.Where(a => !a.IsDynamic)就可以做到呢? - epitka
我的原始答案是基于 .net 2.0 的,这也是我编写代码时所使用的版本。LINQ 和 Assembly.IsDynamic 属性在 .net 2.0 中并不存在。 - Dan Nuffer
3
请注意,应使用AddRange而不是Add(我想纠正它,但无法进行小于6个字符的编辑)。 - phillipwei

16

你引用的是程序集而非命名空间。你应该使用MSDN查找包含所需类的程序集名称:在这种情况下,它将是:

var cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("System.Web.dll");

对我不起作用。 你觉得我应该提供程序集的完整路径吗? 如果是的话; 我可以如何动态执行? - cllpse
3
啊,System.Web.UI.WebControls.dll 不存在--该命名空间中的类实际上在 System.Web.dll 中。 - Tim Robinson

6

在我的情况下,这被证明不太像是蛮力操作。我正在构建一个插件,并且有730个程序集加载在当前域中,因此涉及到了严重的滞后。

var assemblies = someType.Assembly.GetReferencedAssemblies().ToList();
   var assemblyLocations =  
assemblies.Select(a => 
     Assembly.ReflectionOnlyLoad(a.FullName).Location).ToList();

assemblyLocations.Add(someType.Assembly.Location);

cp.ReferencedAssemblies.AddRange(assemblyLocations.ToArray());

1
+1。我使用了你的建议,效果很好。只需要编辑最后一行,写成cp.ReferencedAssemblies.AddRange(assemblyLocations.ToArray());即可。 - Luis Quijada

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接