4

让我试着解释我的问题。我目前正在尝试开发一个用 .Net 编写的小型“插件框架”(主要用于试验)。所以这个想法是有一个主应用程序,可以通过在主应用程序的特定文件夹“插件”中部署 dll 来添加“插件”。一切正常,插件已正确实例化,但是现在我遇到了问题。我现在已经部署了一个插件“X”,它使用了额外的第 3 方插件,所以现在我遇到的问题是在运行时找不到“X”所需的这些额外的第 3 方插件。因此,我现在的想法是添加一个额外的目录“依赖项”,我还部署了所有需要的插件。

所以我的第一个问题:如何将程序集加载到应用程序域中(假设我知道它们的路径)它们可以被我的应用程序使用?

我试图通过做类似的事情来解决这个问题:

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

System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    //find the path to the assembly and then load and return it by
    //return Assembly.Load("pathToDependencies/failedAssembly.dll");
}

问题是这个事件处理程序现在被激活,在 args 变量中有“Presentation.Zune.dll”(我正在使用 WPF 应用程序)。似乎该程序集加载失败,但实际问题是另一个 dll。

有人可以建议我更好的方法来解决我的问题吗?我希望我能够充分解释我的情况,否则只是要求进一步澄清。

谢谢,朱里

4

3 回答 3

9

您可以设置运行时的探测路径,以便它可以找到程序集。在您的应用程序配置文件中设置探测元素。

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="plugins;dependencies"/>
    </assemblyBinding>
  </runtime>
</configuration>
于 2009-02-26T22:27:15.603 回答
2

AssemblyResolve事件在框架尝试加载程序集但失败时发生。

这意味着如果它Presentation.Zune.dll在 args 中为您提供,则框架无法找到该程序集,这是您拦截它并执行其他操作的机会,例如从框架可能不知道的目录中加载它 -例如,您的 plugins\dependencies 文件夹...

在我的脑海中,我会尝试这样的事情:

Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    if( File.Exists(".\\Plugins\\"+args.Name) )  // it's a plugin
        return Assembly.Load(".\\Plugins\\"+args.Name);
    else if( File.Exists(".\\Plugins\\Dependencies\\"+args.Name) )  // it's a dependency OF a plugin
        return Assembly.Load(".\\Plugins\\Dependencies\\"+args.Name);
    else
        throw new Exception();
}
于 2009-02-26T22:21:15.290 回答
1

顺便说一句:如果您缓存已经在字典中解析的程序集,则可以大大加快加载程序集的速度。如果 A 依赖于 B,C 和 B 依赖于 C 并且你加载 A,AssemblyResolve 将为 C 调用两次,并且只加载一次程序集更快:)

(我不确定是否总是多次调用 AssemblyResolve,但我在调试项目一次时注意到了它。缓存程序集并没有什么坏处......)

于 2009-06-14T20:26:33.157 回答