引用加载的程序集

时间:2011-08-03 14:32:47

标签: c# reflection .net-4.0

我不确定如何描述这个最佳。但是我在理解装配体的加载过程时遇到了问题 我的应用程序通过Reflection使用插件。它工作得非常好,我对此非常满意。现在我偶然发现了一个令我困惑的问题,我想我错过了一些东西:
在我的一个模块中,我引用了另一个模块。在运行时,所有模块都已加载。有ClientManager模块和调用模块Calculations。 ClientManager和Calculations都已加载。计算引用ClientManager。当Calculations尝试加载一个ClientManager类时,我得到一个File Not Found-exception 两个程序集都从内存中的字节流加载(通过Assembly.Load(byte []) 当Calculations尝试加载ClientManager类时,它的外观如下:

  

已加载:mscorlib,版本= 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089
  更多组件...
  loaded:ClientManager,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null
  loaded:Calculations,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null
  要加载的程序集的名称:ClientManager,   Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null
  要求来自:Calculations,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null

因此,程序集已加载,但它被请求并且请求失败。我错过了什么?我需要加载两次装配吗?

我很感激任何帮助。

问候,
Skalli

1 个答案:

答案 0 :(得分:2)

您的问题看起来非常类似于我在开发插件时遇到的问题:Where does Visual Studio look for assemblies?

我认为您首先应该了解.NET在寻找程序集的位置,并将其与已在AppDomain中加载的程序集进行比较。这可以使用ProcMon.exe来查看您的应用程序无法找到程序集的位置,并查看可在AppDomain.CurrentDomain.GetAssemblies()中找到的ClientManager的CodeBase属性。

我认为这两条路径会有所不同,但很难想象为什么你的应用在不知情的情况下在不同的地方寻找组件。

最后,我使用AssemblyResolve事件解决了我的问题,只是在当前加载的程序集中查找我的程序集并只是重新编译它(不再重新加载)。

这就是我做的。我不太确定它是否真的很整洁,因为它的工作原理只是因为未找到的组件已经加载:

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    foreach (Assembly anAssembly in AppDomain.CurrentDomain.GetAssemblies())
        if (anAssembly.FullName == args.Name)
            return anAssembly;
    return null;
}