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

查看:132
本文介绍了如何使用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.

推荐答案

我在

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天全站免登陆