BuildManager.GetReferencedAssemblies 等效于非 Web 应用程序

Posted

技术标签:

【中文标题】BuildManager.GetReferencedAssemblies 等效于非 Web 应用程序【英文标题】:BuildManager.GetReferencedAssemblies equivalent for non-web applications 【发布时间】:2012-09-28 13:58:19 【问题描述】:

AppDomain.GetAssemblies() 相比,BuildManager.GetReferencedAssemblies() (System.Web.Compilation.BuildManager) 似乎是一种更可靠的方式来获取 ASP.NET 应用程序在运行时引用的程序集,因为 AppDomain.GetAssemblies() 只获取“具有 已经加载到此应用程序域的执行上下文中”。

遍历所有程序集是在应用程序启动时在 DI 容器中动态注册类型的重要工具,尤其是在应用程序启动期间,可能还没有加载其他程序集(在不需要的地方),并且组合root 是第一个需要它们的人。因此,有一个可靠的方法来获取应用程序引用的程序集是非常重要的。

虽然BuildManager.GetReferencedAssemblies() 是 ASP.NET 应用程序的可靠方法,但我想知道:其他类型的应用程序有哪些替代方法,例如桌面应用程序、Windows 服务和自托管WCF 服务?

【问题讨论】:

【参考方案1】:

我目前看到的唯一方法是手动预取所有引用的程序集,就像 BuildManager 在幕后所做的那样:

var assemblies =
    from file in Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory)
    where Path.GetExtension(file) == ".dll"
    select Assembly.LoadFrom(file);

【讨论】:

这可能在某些时候有效,但到目前为止,我有多个解决方案从各种程序集中调用此代码,尽管操作正确,但它不会获取我所有的“项目 DLL”。我不得不使用这个答案来补充所说的代码:***.com/a/57258916/3997521.【参考方案2】:

我也遇到了同样的问题。在做了一些研究之后,我仍然没有找到一个可靠的答案。我想出的最好的方法是将AppDomain.CurrentDomain.GetAssemblies()AppDomain.AssemblyLoad 事件结合起来。

通过这种方式,我可以处理所有已加载的程序集,同时获得所有新程序集的通知(然后我会对其进行扫描)。

【讨论】:

不幸的是AssemblyLoad 不起作用,因为它会在程序集加载后触发,而问题是程序集没有预取。我正在寻找一种预取程序集的内置机制,就像BuildManager 所做的那样。但也许 .NET 框架没有内置任何东西。 (但麻烦 +1) 不是我发现没有。在这种情况下,您必须手动从应用程序文件夹中加载所有程序集。【参考方案3】:

此解决方案基于@steven 的回答。 但可以在 Web、WinForms、控制台和 Windows 服务中使用。

var binDirectory = String.IsNullOrEmpty(AppDomain.CurrentDomain.RelativeSearchPath) ? AppDomain.CurrentDomain.BaseDirectory : AppDomain.CurrentDomain.RelativeSearchPath;

var assemblies = from file in Directory.GetFiles(binDirectory)
                 where Path.GetExtension(file) == ".dll"
                 select Assembly.LoadFrom(file);

【讨论】:

以上是关于BuildManager.GetReferencedAssemblies 等效于非 Web 应用程序的主要内容,如果未能解决你的问题,请参考以下文章