在ReflectionOnly模式下加载程序集到新的AppDomain时,方法没有实现

5
在我们的应用程序中(包含65个项目的解决方案),所有引用的程序集都会在运行时分析是否存在Ninject模块(也有一些筛选)。稍后,这些模块被加载到Ninject内核中,并且每个模块为内核声明绑定。
我们采用了一个加载器,将引用的程序集以反射方式加载到单独的程序集中。与Ninject可以从目录中加载程序集的方式不同的是,目录中可能包含不应该被加载的模块程序集。并且,在最开始时,并非所有引用的程序集都已加载。
问题在于loader(由Sacha Barber提供)不能加载某些程序集。
System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information

和一个条目的LoaderExceptions

Method 'BeforeLoad' in type 'Lekis.AppBase.Core.BLLBaseCore' from assembly 'AppBaseCore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.

以下是一些“有趣”的事实:

  • BeforeLoad 方法是虚拟的,并且是接口方法的实现
  • 上周加载器异常提示某个不具备实现的方法(该方法不是虚拟的),后来我明确地实现了它,但消息说找不到该方法。
  • 上周程序集 AppBaseCore 的目标框架是 .NET 3.5,3 个程序集未能加载
  • 现在程序集 AppBaseCore 的目标框架是 .NET 4,5 个程序集未能加载
  • 除此之外,应用程序一切正常

显然,我使用 ILSpy 和 ILDAsm 检查这些程序集没有问题。

此时,我真的很迷茫,不知道如何解决这个问题。

非常感谢任何帮助。

谢谢


1
“BeforeLoad”方法是虚拟的,并且是接口方法的实现。但是,确实如此吗?请检查此处的所有答案,以确保您没有遇到某种版本/加载冲突。由于程序集在结构上有效,因此ILSpy / ILDAsm不会报告任何问题。 - Jeroen Mostert
谢谢,@JeroenMostert。我会看一下的。 - Karel Frajták
3个回答

7
回答自己的问题:
当异常被抛出时,我沿着堆栈跟踪向上走,并列出了在创建的子应用程序域中加载的程序集:
AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies()
{System.Reflection.RuntimeAssembly[15]}
...
[13]: {System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}
[14]: {System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}

我注意到System.Data程序集有两个版本。这个方法的一个参数类型是System.Data.IDbTransaction

第一个被引用到的是针对.NET framework 3.5的项目。将其更改为4.0后,一切正常了。

真是一个愚蠢的问题...


2

在调试过程中,我添加了一个异常,当异常被抛出时,我打开了模块窗口(调试菜单--> 窗口 --> 模块,或[Ctrl + D,M]),然后我意识到我的代码正在使用一个与我预期不同的DLL,我用新的DLL替换了旧的DLL,然后它就正常工作了。


0
我刚遇到一个类似的问题,我已经创建了 Microsoft.AspNet.Identity.Core 中 UserManager 类的接口(用于通过 Unity 进行依赖注入)。在单元测试中,我验证了 Unity 的注册情况,尽管我的应用程序编译正确,但我遇到了这个异常。

结果发现,我正在测试的项目和 Unit Test 项目安装了不同版本的 Microsoft.AspNet.Identity.Core(可以通过 NuGet Package Manager 看到)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接