为啥某些 .Net 程序集无法通过 AppDomain 的 GetAssemblies() 方法获得?

Posted

技术标签:

【中文标题】为啥某些 .Net 程序集无法通过 AppDomain 的 GetAssemblies() 方法获得?【英文标题】:Why are some .Net assemblies not available via an AppDomain's GetAssemblies() method?为什么某些 .Net 程序集无法通过 AppDomain 的 GetAssemblies() 方法获得? 【发布时间】:2009-09-09 23:41:22 【问题描述】:

我有一些代码循环遍历当前加载到在 ASP.NET 应用程序中运行的 AppDomain 中的类型。以下是我获取程序集的方式:

var assemblies = AppDomain.CurrentDomain.GetAssemblies();

当应用程序第一次启动时没有问题,并且我期望的所有类型都存在。但是当我更新 Web.config 或终止 w3p.exe 进程(或该进程因任何原因被回收)时,只有我期望的一些类型可用。当我使用调试器单步执行时,我注意到私有搜索路径(我的应用程序的 bin 目录)中的某些程序集尚未加载。我假设所有程序集都在应用程序启动时加载并重新启动,无论它们是否立即需要。但在重新启动的情况下,这似乎不会发生除非这些程序集文件已更新。

我需要的是在启动时收集类型信息以供以后使用。但是由于在重新启动期间类型不可用,因此稍后需要使用类型信息时会产生严重破坏。那么考虑到这一点,我该如何解决或解决这个缺陷?

【问题讨论】:

【参考方案1】:

程序集是按需加载的,因此可能是您尚未使用这些程序集中包含的任何类型。

【讨论】:

是的,我没有在应用启动时加载任何类型。问题是我需要应用程序启动时的类型信息,以便以后可以使用该信息。如果该信息在启动时不可用,则应用可能会在以后崩溃。 您可以使用静态方法 Assembly.Load() 确保在需要时加载所有必需的程序集。 我不能使用 Aseembly.Load() 因为我没有可用的程序集名称。你可能想看看纳德的回答,看看我在哪里。【参考方案2】:

你可以使用

AssemblyName[] assemblies = Assembly.GetCallingAssembly().GetReferencedAssemblies();

这样,您可以从调用这些方法的程序集中获得所有引用的程序集。

【讨论】:

我的调用程序集不一定引用我所追求的类型。 但也许它们被另一个程序集引用,而另一个程序集又被您的程序集引用。您可以遍历间接引用程序集的整个树以获得所需的所有程序集/类型。 啊,我明白了。我可以做到。我将不得不看看这如何有助于启动时间。谢谢。 原来我不能这样做,因为调用程序集甚至执行程序集都不会,甚至间接地引用我感兴趣的类型。【参考方案3】:

作为启动的一部分,你能explicitly load你关心的程序集吗?

您必须提前知道您需要哪些程序集。

扫描文件系统以找出与您的应用程序一起提供的程序集可能是一个有用的想法,但对于 GAC 加载的程序集没有帮助...

【讨论】:

我正在考虑显式加载程序集。到目前为止,我只需要私有程序集,因此我可以从私有搜索路径中加载所有内容。我不确定这是实现这一目标的最佳方法。组装。加载?程序集.LoadFile? Assembly.LoadFrom? Assembly.Load 通常是首选方法,因为它最接近正常加载机制。有关优点和缺点,请参阅 blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx,有关更多信息,请参阅 blogs.msdn.com/suzcook/archive/2003/09/19/57248.aspx。 感谢您的链接,我已经看过了。我想我必须使用 LoadFrom 或 LoadFile,因为我只有文件路径可以使用。我知道我什么时候使用过 LoadFile,然后在部署期间更新程序集时遇到问题,因为程序集文件被锁定,大概是由 LoadFile 锁定的。我认为 LoadFrom 适合我,但我不确定我是否完全理解它的含义。 如果您只有路径可以使用,您可以检查这些程序集以找出路径吗?获得正确的绑定上下文很重要。此外,就文件锁定问题而言,您应该在部署时关闭应用程序池 - 这将关闭 IIS 进程并防止锁定。如果您不想这样做,另一种选择是执行 ASP.NET 所做的操作:创建卷影副本 (techbubble.net/Blog/tabid/57/EntryId/148/…) 纳德,再次感谢。我只是不确定如何确定哪个绑定上下文对我来说是正确的。到目前为止,LoadFrom 正在工作,并且我已经尽我所能验证了我具有预期的行为。但话又说回来,在我注意到我有这个问题之前,情况就是这样。 :)

以上是关于为啥某些 .Net 程序集无法通过 AppDomain 的 GetAssemblies() 方法获得?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 AppDomain.CurrentDomain.GetAssemblies() 在某些情况下不返回 Global.asax 中的依赖程序集?

为啥强制降级会导致 .Net Core 中的程序集加载异常?

为啥在尝试添加引用时会看到“无法发出程序集:引用的程序集...没有强名称”?

为啥我使用 unshare(CLONE_NEWUSER) 后无法运行某些程序

Azure 应用服务无法访问文件,因此甚至无法加载程序集

为啥即使在添加程序集“Microsoft.SqlServer.ConnectionInfo”之后 C# 也无法识别 Server()