ASP.NET 4.5 应用程序预热导致错误确定已加载程序集

ASP.NET 4.5 application warmup causes error determining loaded assemblies

我有一个我们在所有 Web 应用程序中使用的库模块,它在 [=34] 的 Application_Start 方法中列出所有加载的程序集(及其版本号)到我们的 log4net 日志文件中=] 网络表单应用程序。

这多年来一直完美无缺 - 直到今天,当我尝试在 "application warmup" 方法之后使用它时(Scott Guthrie in his blog post 描述的 运行 在部署到 IIS 之后(和 之前 ASP.NET的Application_Start曾经运行) - 现在我突然得到一个错误:

System.NotSupportedException: The invoked member is not supported in a dynamic assembly.

报告已加载程序集的代码如下所示:

public static void ReportLoadedAssemblies(this ILog log) 
{
    if (log.IsInfoEnabled) 
    {
        log.Info("Loaded assemblies:");

        IEnumerable<Assembly> appAssemblies = AppDomain.CurrentDomain.GetAssemblies().OrderBy(c => c.ManifestModule.Name);

        foreach (Assembly asm in appAssemblies) 
        {
            FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(asm.Location);

            if (!fvi.CompanyName.Contains("Microsoft")) 
            {
                log.Info(String.Format("{0, -45} : {1, -15} {2}", fvi.FileDescription, fvi.FileVersion, asm.Location));
            }
        }
    }
}

我不是 100% 清楚到底是哪一行引发了错误 - 我 怀疑 是这一行:

IEnumerable<Assembly> appAssemblies = AppDomain.CurrentDomain.GetAssemblies().OrderBy(c => c.ManifestModule.Name);

所以这条消息到底是想告诉我什么?在这种情况下我怎样才能得到我加载的程序集?

我认为错误不在

IEnumerable<Assembly> appAssemblies = AppDomain.CurrentDomain.GetAssemblies().OrderBy(c => c.ManifestModule.Name);

因为动态生成程序集时访问Assembly.Location属性会抛出NotSupportedException

So what exactly is this message telling me?

如果动态生成的程序集没有任何位置,那么您将无法访问它 属性。是的,它可能 return 是一个空字符串,但它与使用 Assembly.Load() 创建的程序集相同......说真的,我无法理解这种选择的理由,但仅此而已。

And how can I still get my loaded assemblies in this situation?

只需检查一下:

foreach (Assembly asm in appAssemblies.Where(x => !x.IsDynamic)) 
{
    // Your code
}   

或更简单:

var appAssemblies = AppDomain.CurrentDomain.GetAssemblies()
    .Where(x => !x.IsDynamic)
    .OrderBy(c => c.ManifestModule.Name);