.net - 如何使用 CodeDOM 在 AppDomain 中创建和加载程序集?

标签 .net appdomain codedom

我正在开发一个项目,该项目将使用 CodeDOM 创建一个类,该类评估用户定义的表达式、为该类创建程序集并加载该程序集。由于可以有相当数量的用户定义表达式,我想首先创建一个 AppDomain,为该 AppDomain 中的程序集执行 CodeDOM 创建/加载和执行,然后卸载 AppDomain。

我已经搜索了很多,并找到了许多关于如何将现有程序集加载到 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 中。

最佳答案

我在 http://www.softwareinteractions.com/blog/2010/2/7/loading-and-unloading-net-assemblies.html 找到了我正在寻找的答案.他有一篇很好的文章,详细介绍了 AppDomain 的创建和作为插件加载程序集。我按照他的例子,能够创建一个 AppDomain,为我的 ExpressionEvaluator 类工厂创建一个代理,并成功调用它并接收结果。

关于.net - 如何使用 CodeDOM 在 AppDomain 中创建和加载程序集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3512931/

相关文章:

c# - 如何格式化 DateTime 结构,使其与 DataContractJsonSerializer 使用的格式相匹配?

.net - WPF 中的 NameScope 如何工作?

c# - 在C#中动态替换DLL

generics - CodeDom - 调用通用方法

c# - 如何在不将嵌入式资源写入磁盘的情况下将其读取为字节数组?

C# .NET 远程处理服务器和 Java 客户端

c# - 如何在azure中获取VM的核心数

c# - 如何即时编译、加载和使用 C# DLL

c# - 在单独的 AppDomain 中传递和执行委托(delegate)

C# 代码编译后的 .exe 无法运行