.net 如何使用CodeDOM在AppDomain中创建和加载程序集?
我正在从事一个项目,该项目将使用CodeDOM创建一个类,该类对用户定义的表达式求值,为该类创建一个程序集,并加载该程序集。由于可能有相当数量的用户定义表达式,我想首先创建一个AppDomain,在该AppDomain中为程序集执行CodeDOM创建/加载和执行,然后卸载AppDomain 我搜索了很多,找到了很多如何将现有程序集加载到AppDomain的示例,但似乎找不到一个示例演示如何从AppDomain中创建程序集 本例()使用CodeDOM创建一个程序集,然后将其加载到AppDomain中,但是,作者正在将程序集生成到磁盘。我更喜欢在内存中生成程序集,这样我就不必管理所生成程序集的清理。(即使这会在临时文件夹中创建.dll) 有人能给我举个例子说明如何做到这一点吗 任何帮助都将不胜感激 我已经从我的代码中摘录了一些内容,以便大家都能感受到我到目前为止所做的工作:.net 如何使用CodeDOM在AppDomain中创建和加载程序集?,.net,appdomain,codedom,.net,Appdomain,Codedom,我正在从事一个项目,该项目将使用CodeDOM创建一个类,该类对用户定义的表达式求值,为该类创建一个程序集,并加载该程序集。由于可能有相当数量的用户定义表达式,我想首先创建一个AppDomain,在该AppDomain中为程序集执行CodeDOM创建/加载和执行,然后卸载AppDomain 我搜索了很多,找到了很多如何将现有程序集加载到AppDomain的示例,但似乎找不到一个示例演示如何从AppDomain中创建程序集 本例()使用CodeDOM创建一个程序集,然后将其加载到AppDomain
private string CreateSource()
{
CodeCompileUnit codeUnit = new CodeCompileUnit();
CodeNamespace codeNamespace = new CodeNamespace(Namespace);
CodeTypeDeclaration codeClass = new CodeTypeDeclaration
{
Name = "ExpressionEvaluator",
IsClass = true,
TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed
};
codeNamespace.Types.Add(codeClass);
codeUnit.Namespaces.Add(codeNamespace);
AddMethods(codeClass);
string result = GenerateSourceCode(codeUnit);
return result.ToString();
}
private CompilerResults CompileSource(string source)
{
using (CodeDomProvider provider = new CSharpCodeProvider())
{
CompilerParameters parameters = CreateCompilerParameters();
CompilerResults result = CompileCode(provider, parameters, source);
return result;
}
}
private static CompilerParameters CreateCompilerParameters()
{
CompilerParameters result = new CompilerParameters
{
CompilerOptions = "/target:library",
GenerateExecutable = false,
GenerateInMemory = true
};
result.ReferencedAssemblies.Add("System.dll");
return result;
}
private object RunEvaluator(CompilerResults compilerResults)
{
object result = null;
Assembly assembly = compilerResults.CompiledAssembly;
if (assembly != null)
{
string className = "ExpressionEvaluator";
object instance = assembly.CreateInstance("Lab.ExpressionEvaluator");
Module[] modules = assembly.GetModules(false);
Type type = (from t in modules[0].GetTypes()
where t.Name == className
select t).FirstOrDefault();
MethodInfo method = (from m in type.GetMethods()
where m.Name == "Evaluate"
select m).FirstOrDefault();
result = method.Invoke(instance, null);
}
else
{
throw new Exception("Unable to load Evaluator assembly");
}
return result;
}
我相信这些代码片段展示了我的项目的基本功能。现在,我需要做的就是将其包装到自己的AppDomain中。只需使用
AssemblyBuilderAccess。定义
可以执行动态程序集,但不能保存
鸡和蛋的问题。您需要一个小的引导程序集,可以加载到新的AppDomain中。使用一个著名的类加载CodeDom生成的程序集并使其运行
使用GenerateInMemory执行此操作是毫无意义的,您必须将其序列化到新的AppDomain中。这只是一堆开销,不妨从磁盘加载,反正它就在那里。它已经在记忆中了。文件系统缓存的内存。加载它会非常快,因为它实际上不需要从磁盘上读取。我找到了我想要的答案。他有一篇很好的文章,详细介绍了AppDomain的创建和作为插件加载程序集。我遵循他的示例,能够创建一个AppDomain,为我的ExpressionEvaluator类工厂创建一个代理,并成功地调用它并接收结果。在所有这些中,compileCode
方法从何而来?这似乎是最重要的部分,您决定将其忽略?我相信您混淆了反射。使用CodeDom发射。谢谢Joel。我正在研究动态程序集。CompileCode
方法与这个问题并不密切相关,这个问题是如何在运行时生成源代码、创建程序集并将其加载到AppDomain
。我意识到我最初的问题可能并不是对我的问题的完全准确的描述,但随着我收到反馈并做了更多的研究,它细化了问题的范围和定义。具体来说,就是我试图执行的操作顺序。接受答案中的文章阐明了我需要采取的方法,并帮助我解决了问题。现在这是一个死链接。@David L: