我正在开发一个项目,使用CodeDOM创建一个类来评估用户定义的表达式,创建一个该类的程序集,并加载该程序集。由于可能有相当数量的用户定义的表达式,我想首先创建一个AppDomain,在该AppDomain中执行CodeDOM的创建/加载和程序集的执行,然后卸载AppDomain。
我已经搜索了很多,找到了许多将现有程序集加载到AppDomain中的示例,但似乎找不到一个显示如何从AppDomain内部创建程序集的示例。
这个例子(DynamicCode)使用CodeDOM创建一个程序集,然后将其加载到AppDomain中,但是,作者是将程序集生成到磁盘上的。我更喜欢在内存中生成程序集,这样我就不必管理生成的程序集的清理(即使这会在临时文件夹中创建一个.dll)。
有人能指点我如何做吗?
任何帮助都将不胜感激。
我包含了一些我的代码摘录,这样你们就可以了解我目前的情况:
我已经搜索了很多,找到了许多将现有程序集加载到AppDomain中的示例,但似乎找不到一个显示如何从AppDomain内部创建程序集的示例。
这个例子(DynamicCode)使用CodeDOM创建一个程序集,然后将其加载到AppDomain中,但是,作者是将程序集生成到磁盘上的。我更喜欢在内存中生成程序集,这样我就不必管理生成的程序集的清理(即使这会在临时文件夹中创建一个.dll)。
有人能指点我如何做吗?
任何帮助都将不胜感激。
我包含了一些我的代码摘录,这样你们就可以了解我目前的情况:
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中。