如何使用 CodeDOM 在 AppDomain 中创建和加载程序集? [英] How can I use CodeDOM to create and load an assembly in an AppDomain?

查看:25
本文介绍了如何使用 CodeDOM 在 AppDomain 中创建和加载程序集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on a project that will use CodeDOM to create a class that evaluates a user-defined expression, creates an assembly for the class, and loads the assembly. Since there can be a fair number of user-defined expressions, I would like to first create an AppDomain, execute the CodeDOM creation/loading and executing for the assembly within that AppDomain, and then unload the AppDomain.

我搜索了很多,找到了很多关于如何将现有程序集加载到 AppDomain 中的示例,但我似乎找不到一个向我展示如何从 内创建程序集 AppDomain.

I've searched quite a bit, and found many examples of how to load an existing assembly into an AppDomain, but I can't seem to find one that shows me how to create the assembly from within the AppDomain.

此示例 (DynamicCode) 使用 CodeDOM 创建程序集,并且然后将其加载到 AppDomain 中,但是,作者正在将程序集生成到磁盘.我更愿意在内存中生成程序集,这样我就不必管理生成的程序集的清理工作.(即使这会在临时文件夹中创建一个 .dll).

This example (DynamicCode) creates an assembly using CodeDOM, and then loads it into an AppDomain, however, the author is generating the assembly to disk. I would prefer to generate the assembly in memory, so that I do not have to manage the cleanup of the generated assemblies. (even though this does create a .dll in a temp folder).

谁能给我举个例子来说明如何做到这一点?

Can anyone point me to an example of how to do this?

任何帮助将不胜感激.

我已经从我的代码中摘录了一些摘录,以便你们都可以了解我目前所拥有的内容:

I've included some excerpts from my code so you can all get a feel for what I have so far:

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 中.

I believe these code snippets show the basic functionality of my project. Now all I need to do is wrap it in its own AppDomain.

推荐答案

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

I found the answer that I was looking for at http://www.softwareinteractions.com/blog/2010/2/7/loading-and-unloading-net-assemblies.html. He has a nice article detailing the creation of an AppDomain and loading an assembly as a plugin. I followed his example and was able to create an AppDomain, create a proxy for my ExpressionEvaluator class factory and successfully call it and receive results.

这篇关于如何使用 CodeDOM 在 AppDomain 中创建和加载程序集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆