C#-在动态生成的程序集中引用类型

C#-在动态生成的程序集中引用类型,c#,dynamic,assemblies,reference,C#,Dynamic,Assemblies,Reference,我试图弄清楚,在动态生成程序集时,是否可以引用以前动态生成的程序集中的类型 例如: using System; using System.CodeDom.Compiler; using System.Reflection; using Microsoft.CSharp; CodeDomProvider provider = new CSharpCodeProvider(); CompilerParameters parameters = new CompilerParameters(); p

我试图弄清楚,在动态生成程序集时,是否可以引用以前动态生成的程序集中的类型

例如:

using System;
using System.CodeDom.Compiler;
using System.Reflection;
using Microsoft.CSharp;

CodeDomProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();

parameters.GenerateInMemory = true;

CompilerResults results = provider.CompileAssemblyFromSource(parameters, @"
namespace Dynamic
{
    public class A
    {
    }
}
");

Assembly assem = results.CompiledAssembly;

CodeDomProvider provider2 = new CSharpCodeProvider();
CompilerParameters parameters2 = new CompilerParameters();

parameters2.ReferencedAssemblies.Add(assem.FullName);
parameters2.GenerateInMemory = true;

CompilerResults results2 = provider2.CompileAssemblyFromSource(parameters2, @"
namespace Dynamic
{
    public class B : A
    {
    }
}
");

if (results2.Errors.HasErrors)
{
    foreach (CompilerError error in results2.Errors)
    {
        Console.WriteLine(error.ErrorText);
    }
}
else
{
    Assembly assem2 = results2.CompiledAssembly;
}
此代码在控制台上打印以下内容:
找不到类型或命名空间名称“A”(是否缺少using指令或程序集引用?

我试过很多不同的方法,但似乎都不管用。我错过什么了吗?这可能吗

编辑:修复代码中的错误会导致以下错误:
找不到元数据文件“l0livsmn,版本=0.0.0,区域性=中立,PublicKeyToken=null”

EDIT2:有点旁注,但将GenerateInMemory更改为false,并执行
parameters2.ReferencedAssemblys.Add(assem.Location)将使它正确编译,但我更喜欢直接引用内存中的程序集,而不是输出临时文件

CompilerResults results2 = provider2.CompileAssemblyFromSource(parameters, @"
namespace Dynamic
{
    public class B : A
    {
    }
}
");
您要传递的是
参数2
,而不是
参数

我找到了这样做的方法,你不需要编译内存中的第一个,如果你不这样做,它会在你的临时目录中为这个程序集创建一个dll,另外,在你调用

ReferencedAssemblies.Add() 
你没有传递程序集名称,你传递了程序集路径,看看这段代码,它应该可以完美地工作:

        CodeDomProvider provider = new CSharpCodeProvider();
        CompilerParameters parameters = new CompilerParameters();            

        CompilerResults results = provider.CompileAssemblyFromSource(parameters, @"
            namespace Dynamic
            {
                public class A
                {
                }
            }
            ");

        Assembly assem = results.CompiledAssembly;

        CodeDomProvider provider2 = new CSharpCodeProvider();
        CompilerParameters parameters2 = new CompilerParameters();

        parameters2.ReferencedAssemblies.Add(assem.Location);
        parameters2.GenerateInMemory = true;

        CompilerResults results2 = provider2.CompileAssemblyFromSource(parameters2, @"
            namespace Dynamic
            {
                public class B : A
                {
                }
            }
            ");

        if (results2.Errors.HasErrors)
        {
            foreach (CompilerError error in results2.Errors)
            {
                Console.WriteLine(error.ErrorText);
            }
        }
        else
        {
            Assembly assem2 = results2.CompiledAssembly;
        }
说你可以:

类型引用限制

程序集可以引用定义的类型 在另一个集合中。短暂的 动态装配可以安全地引用 在另一个瞬态中定义的类型 动态程序集,一个持久化的 动态装配或静态装配 装配然而,共同的 语言运行库不允许 持久化动态模块 引用中定义的类型 瞬态动态模块。这是 因为当持久化的动态 模块在保存到后加载 磁盘,运行时无法解析 对中定义的类型的引用 瞬态动态模块


好吧,我想现在的问题是,“如何在内存中引用瞬态动态程序集?”我想知道:程序集是在内存中创建的,但是默认情况下它是否添加到ApplicationDomain中?还是你自己装?或者调用AppDomain.DefinedDynamicAssembly
?嗯,这是个好问题。我试着玩了一下,动态生成的程序集似乎已经加载了。我也遇到了类似的问题!在我的代码中,我无法获得要定义的assem.Location。所有内容都在内存中加载和运行。我用什么做这个?调试器说它不是指定的属性。请参阅我的第二次编辑。我想我们大概是在同一时间发现的。如果可能的话,我仍然希望能够引用内存中的程序集。看起来源代码运行并创建了第二个程序集。但是,如果您尝试加载驻留在第二个程序集中的类型(使用assem2.GetTypes()),您将在第一个程序集中获得ReflectionTypeLoadException输出dll存储在temp文件夹中。要使用它,您必须将其保存在应用程序目录中,或添加搜索路径,如中所述