我有两个完全不同的目录。目录1包含我的应用程序,目录2包含少量程序集。在应用程序启动的运行时,我将加载程序集。默认情况下,执行程序集的AppDomain将发现目录1(应用程序文件夹)或GAC中的程序集。如果文件不存在,我们将收到错误。但我必须扩展AppDomain的搜索目录,以便在目录2中进行搜索。也就是说,AppDomain将搜索Directory1(本地bin),然后搜索GAC,然后搜索目录2中最后一次搜索的其他默认值。
我试过了: 1.通过设置PrivateBinPath,但它仅限于ApplicationBaseDirectory中。 2.通过AssemblyResolve,但它没有直接引用。 AssemblyResolve代码也不会命中。
答案 0 :(得分:0)
使用AssemblyResolve
事件通常是正确的方法。如果它永远不会被击中,它可能已经太晚了。例如,当CLR遇到一个方法时,它将完全编译它,解析它的所有引用。如果这样的解决方案失败,它将永远失败。如果在任何或所有程序集绑定失败后绑定AssemblyResolve
事件,则事件永远不会命中。
要解决此问题,请确保尽早绑定AssemblyResolve
事件。在可执行文件中,这很容易(首先在应用程序的入口点,或者您在其中使用的任何cctor
类型)。在库中,这可能更难,最佳实践方法是使用模块初始化程序,它在加载模块时运行(大多数程序集包含一个模块)。
由于模块初始值设定项不能由C#或我所知的任何其他.NET语言设置,因此必须使用方法编织。我个人喜欢Fody,事实证明,有一个名为Fody Module Init的预定义Fody包就是这个。
只需在您的图书馆中公开放置以下代码:
public static class ModuleInitializer
{
public static void Initialize()
{
// bind to the CurrentDomain.AssemblyResolve event
}
}
Fody也适用于其他语言(您没有指定使用哪种语言),但是您必须手动创建静态ModuleInitializer
类。
使用这种方法,您可以确定将为CLR的Fusion无法自行找到的任何程序集调用AssemblyResolve
事件 。