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

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

创建System.Reflection.Emit.AssemblyBuilder时,可以将其持久化(使用AssemblyBuilderAccess.Save和类似工具初始化)或暂时化(AssemblyBuilderAccess.Run和类似工具)。我将为作为输入的assembly builder创建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);
    }
}

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

刚刚遇到了这个确切的情况-您可以处理这个问题的唯一实际方法是,无需传入状态变量来说明程序集是否是可持久的,即:

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。