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文件夹中。要使用它,您必须将其保存在应用程序目录中,或添加搜索路径,如中所述