C# 检查.NET动态程序集是暂时的还是持久的
创建System.Reflection.Emit.AssemblyBuilder时,可以将其持久化(使用AssemblyBuilderAccess.Save和类似工具初始化)或暂时化(AssemblyBuilderAccess.Run和类似工具)。我将为作为输入的assembly builder创建ModuleBuilder。但是不能为临时程序集创建持久化模块,所以我必须在创建模块之前检查程序集的状态。我该怎么做?该片段是:C# 检查.NET动态程序集是暂时的还是持久的,c#,.net,reflection,reflection.emit,C#,.net,Reflection,Reflection.emit,创建System.Reflection.Emit.AssemblyBuilder时,可以将其持久化(使用AssemblyBuilderAccess.Save和类似工具初始化)或暂时化(AssemblyBuilderAccess.Run和类似工具)。我将为作为输入的assembly builder创建ModuleBuilder。但是不能为临时程序集创建持久化模块,所以我必须在创建模块之前检查程序集的状态。我该怎么做?该片段是: public ModuleBuilder Handle(Assembl
public ModuleBuilder Handle(AssemblyBuilder assembly, string name)
{
if (assembly.IsPersisted) // IsPersisted is a kind of property I'm looking for
{
return assembly.DefineDynamicModule(name, name + ".dll");
}
else
{
return assembly.DefineDynamicModule(name);
}
}
我可以通过使用反射访问程序集的内部字段来获取程序集状态,因此这不是我要寻找的答案。刚刚遇到了这个确切的情况-您可以处理这个问题的唯一实际方法是,无需传入状态变量来说明程序集是否是可持久的,即:
try
{
return assembly.DefineDynamicModule(name, name + ".dll");
}
catch(NotSupportedException)
{
return assembly.DefineDynamicModule(name);
}
不漂亮-但没有真正的替代方案。您可以通过反射来实现这一点,但您应该包装您的具体实现以处理不祥的异常,因为这依赖于内部实现,因此无法保证API的持久性
if (assembly.IsDynamic)
{
Type assemblyType = assembly.GetType();
Type assemblyBuilderDataType = Assembly.GetAssembly(assemblyType)
.GetType("System.Reflection.Emit.AssemblyBuilderData");
object assemblyBuilderData = assemblyType
.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
.Single(fi => fi.FieldType == assemblyBuilderDataType)
.GetValue(assembly);
object assemblyBuilderAccess = assemblyBuilderDataType
.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
.Single(fi => fi.FieldType == typeof(AssemblyBuilderAccess))
.GetValue(assemblyBuilderData);
switch (assemblyBuilderAccess)
{
…
}
}
只是一个猜测,但是assembly.CodeBase给了你什么呢。IIRC是磁盘上exe或dll文件的路径。如果没有持久化,这可能会给出一个线索。为什么要将模块与程序集分开创建?您几乎总是希望每个程序集中只有一个模块。@simon at rcl:这个想法很有趣,但在这两种情况下我都得到了NotSupportedException。assembly.Location呢?抱歉,这就是我的意思;不知道我为什么会想到代码库。如果这不起作用,那么可能值得检查基本exe文件的代码库:如果它不返回异常,那么也许您可以使用这个事实:异常=未持久化?@svick:因为SRP。从一方面来说,我有大量的程序集创建扩展(设为N),可以进行扩展。从另一方面来看,大量的模块创建例程(M)。通过将AssemblyBuilder传递给这些例程,我可以混合不同的排放策略。如果我把它们放在一起,我得到的是N*M的复杂度,而不是N+M。