【问题标题】:C# Reflection -- Load external DLL's and all dependenciesC# 反射——加载外部 DLL 和所有依赖项
【发布时间】:2012-12-03 06:55:40
【问题描述】:

我正在尝试使用反射为.NET 完成(似乎是)一个极其简单的依赖注入机制。目标是为 ServiceFactory 类提供接口,并使用反射来确定该接口的可用实现者,并根据 App.config 部分选择实现。听起来很简单。

我选择的路线是使用每个服务实现项目的构建后事件将实现 .dll 复制到“ServiceImplementations”文件夹中。然后,ServiceFactory 类在此文件夹中查找可用的、有效的接口实现者。这个想法是,使用反射,我应该能够在运行时纯粹在反射中加载这个任意 DLL 及其所有依赖项。这是我希望达到的目标。

在这个过程的某个地方,我正在加载这些依赖项。我可以检查我当前加载的程序集 var asmDomainAssemblies = AppDomain.CurrentDomain.GetAssemblies()

因此,我继续进行反射爬网,并最终加载依赖程序集(在本例中为 EntityFramework,通过 NuGet 加载,以及 System.Web.ApplicationServices,一个系统文件)。一切都很好。直到我到达这行代码:

        var serviceImplementationAssembly = CheckLoadedAssemblies(assemblyName);  // This function loads the service implementation assembly and its dependencies
        var appDomainAsm = AppDomain.CurrentDomain.GetAssemblies();
        var implementationTypes = serviceImplementationNamespace.GetTypes();      // Exception here

在最后一行代码中,抛出了 ReflectionTypeLoadException。此异常包含两个 LoaderExceptions(每个都是 FileNotFoundException),并带有以下消息:

         Could not load file or assembly 'EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.":"EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

这很奇怪。如果我检查上面的 asmDomainAsm 变量,我可以看到在我当前的 AppDomain 中加载了确切的程序集签名 is。我不明白为什么 Reflection 不能识别这些是相同的程序集,即使我在不​​同时间加载它们。

提前感谢您的帮助。

【问题讨论】:

  • 作为异常状态,它也很可能是 EntityFramework 所依赖的程序集之一,而不是 EntityFramework 程序集本身。您可能想尝试一下 Fusion Logviewer:msdn.microsoft.com/en-us/library/e74a18c4.aspx
  • 您是否可以使用Assembly.LoadFromAssembly.LoadFile 动态加载EntityFramework 程序集?
  • @mikez 是的,这正是我所做的。这有什么问题吗?
  • @bitbonk 自己查了一下,没有其他依赖。 EntityFramework 是一个独立的程序集。无论如何,我已经在我递归加载的每个程序集上运行了 Assembly.GetReferencedAssemblies,因此无论如何这都不是问题。
  • 您仍然应该尝试使用 Fusion Log Viewer,因为它可以为您提供有关任何失败的程序集绑定的更多详细信息。

标签: c# reflection dependency-injection system.reflection


【解决方案1】:

我终于让它工作了。本质上,我试图手动处理 AssemblyResolve 事件,方法是加载每个程序集,检查其依赖关系,并在我喜欢的任何时候触发 Assembly.Load 和 Assembly.LoadFile 事件。当我添加一个 CurrentDomain_AssemblyResolve 事件时,该事件在触发时运行我的自定义目录搜索/程序集加载代码,一切正常。

由于一些内部 AppDomain / BundleContext 问题,引发了异常。切换到 AssemblyResolve 解决了我的问题。不幸的是,这就是我所知道的一切。如果有人可以在这里解释幕后发生的事情,我将接受答案。

【讨论】:

  • 这正是我所建议的。文档描述了此行为 (msdn.microsoft.com/en-us/library/1009fa28(v=vs.110).aspx),其中“如果使用 LoadFrom 加载程序集,然后加载上下文中的程序集尝试按显示名称加载相同的程序集,则加载尝试将失败。”但除非你已经意识到这个问题,否则它并没有多大帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-22
  • 1970-01-01
  • 1970-01-01
  • 2017-04-14
相关资源
最近更新 更多