【问题标题】:BuildManager.GetReferencedAssemblies equivalent for non-web applicationsBuildManager.GetReferencedAssemblies 等效于非 Web 应用程序
【发布时间】: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 服务?

【问题讨论】:

    标签: asp.net asp.net-mvc winforms wcf asp.net-web-api


    【解决方案1】:

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

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

    【讨论】:

    • 这可能在某些时候有效,但到目前为止,我有多个解决方案从各种程序集中调用此代码,尽管操作正确,但它不会获取我所有的“项目 DLL”。我不得不使用这个答案来补充所说的代码:stackoverflow.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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-23
      相关资源
      最近更新 更多