检查.NET动态程序集是暂时的还是持久的

时间:2014-06-18 12:15:05

标签: c# .net reflection reflection.emit

当创建System.Reflection.Emit.AssemblyBuilder时,它可以持久化(使用AssemblyBuilderAccess.Save和类似方法初始化)或者瞬态(AssemblyBuilderAccess.Run等)。我将为装配构建器创建ModuleBuilder,我有输入。但是不能为瞬态汇编创建持久模块,因此我必须在创建模块之前检查汇编的状态。我怎样才能做到这一点?摘录如下:

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);
    }
}

我可以通过使用反射访问其内部字段来获取程序集状态,因此这不是我正在寻找的答案。

2 个答案:

答案 0 :(得分:0)

刚刚遇到这种情况 - 你可以处理这个问题的唯一真正方法是,不传递状态变量,说明程序集是否可以持久化,是:

try
{
    return assembly.DefineDynamicModule(name, name + ".dll");
}
catch(NotSupportedException)
{
    return assembly.DefineDynamicModule(name);
}

不漂亮 - 但没有真正的选择。

答案 1 :(得分:0)

您可以通过反思来做到这一点,但是您应该包装具体的实现以处理不祥的异常,因为这依赖于内部实现,因此无法保证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)
        {
                …
        }
}