11

这是设置:

纯 DotNET 类库由非托管桌面应用程序加载。类库充当插件。这个插件加载它自己的小插件(所有 DotNET 类库),它通过将 dll 作为字节流读入内存来实现,然后

Assembly asm = Assembly.Load(COFF_Image);

当这些小宝贝插件引用其他 dll 时,就会出现问题。由于它们是通过内存而不是直接从磁盘加载的,因此框架通常找不到这些引用的程序集,因此无法加载它们。

我可以在我的项目中添加一个 AssemblyResolver 处理程序,我可以看到这些引用的程序集消失了。我对在磁盘上的哪里可以找到这些引用的程序集有一个相当好的想法,但是我怎样才能确保我加载的程序集是正确的呢?

简而言之,我如何可靠地从 System.ResolveEventArgs.Name 字段转到 dll 文件路径,假设我有一个该 dll 可能隐藏的所有文件夹的列表)?

4

3 回答 3

7

当我过去使用它时,我们只是将文件名与具有该名称的 ResolveEventArgs.Name 部分进行了比较。如果您想确保加载完全相同的版本,我想您可以检查名称是否匹配,如果匹配,则加载程序集,然后根据 ResolveEventArgs.Name 检查程序集的全名。

这些方面的东西:

string name = GetAssemblyName (args); //gets just the name part of the assembly name
foreach (string searchDirectory in m_searchDirectories)
    {
    string assemblyPath = Path.Combine (executingAssemblyPath, searchDirectory);
    assemblyPath = Path.Combine (assemblyPath, name + ".dll");        
    if (File.Exists (assemblyPath))
        {            
        Assembly assembly = Assembly.LoadFrom (assemblyPath);
        if (assembly.FullName == args.Name)
            return assembly;
        }
    }

为了完整性:

private string GetAssemblyName (ResolveEventArgs args)
    {
    String name;
    if (args.Name.IndexOf (",") > -1)
        {
        name = args.Name.Substring (0, args.Name.IndexOf (","));
        }
    else
        {
        name = args.Name;
        }
    return name;
    }
于 2010-04-28T12:55:50.490 回答
2

托管可扩展性框架 (MEF)听起来可以解决您的所有问题。它可以扫描文件夹以定位 DLL,解决任何深度的依赖关系并管理插件组合。每个部分(或“插件”)只需要声明它需要什么以及提供什么,MEF 负责接线。如果 MEF 成功驯服了 VS2010 的可扩展性野兽,那么它可以处理任何事情。

于 2010-04-28T13:23:25.103 回答
1

我从来没有使用 AssemblyResolver 运气。我通常做这三个之一:

  1. 要求插件没有 GAC 中没有的外部引用。如果他们讨厌,请告诉他们ILMerge
  2. 要求插件将其所有 dll 转储到已知的插件目录中。将该目录中的所有程序集加载到内存中。
  3. 要求插件依赖项存在于融合探测的路径中。您可以找出活页夹在哪里寻找程序集打开融合日志(fuslogvw.exe - 不要忘记在打开日志记录后重新启动!)。
于 2010-04-28T12:55:15.130 回答