C# AppDomain依赖项解析顺序

C# AppDomain依赖项解析顺序,c#,.net,reflection,C#,.net,Reflection,我有一个类似于调度器的.Net多appdomain应用程序。默认应用程序域有一个计时器和一个作业列表,每个作业都包含在自己的程序集中,并在单独的应用程序域上运行。包含作业的程序集分别保存在应用程序根目录下的单独目录中 (root)\Library\AssemblyName\ 每个程序集目录都包含程序集及其依赖项。其中一些依赖项(例如log4net)也包含在根目录中,因为默认域有单独的日志。如果存在作业程序集及其依赖项,我希望从程序集目录加载它们,如果不存在,我希望从应用程序根目录加载它们。主a

我有一个类似于调度器的.Net多appdomain应用程序。默认应用程序域有一个计时器和一个作业列表,每个作业都包含在自己的程序集中,并在单独的应用程序域上运行。包含作业的程序集分别保存在应用程序根目录下的单独目录中

(root)\Library\AssemblyName\
每个程序集目录都包含程序集及其依赖项。其中一些依赖项(例如log4net)也包含在根目录中,因为默认域有单独的日志。如果存在作业程序集及其依赖项,我希望从程序集目录加载它们,如果不存在,我希望从应用程序根目录加载它们。主appdomain和子域都使用相同的库,其接口类似于Quartz的IJob接口,因此需要从同一文件加载此程序集

这个要求相当奇怪的原因是应用程序作业应该具有自动更新能力。因此,专门设计的类将从API下载作业,卸载作业所在的appdomain,删除具有所有依赖项的作业程序集,重新加载appdomain并重新启动作业,而不会干扰其他作业的操作。我尝试使用AppdomainSetup将程序集目录设置在根目录之前

domainSetup.PrivateBinPath = @"\\Library\\AssemblyName\\" 
但是,我的依赖项每次都从根目录得到解析

所以基本上我希望我的依赖关系从 1.程序集文件夹(如果可能) 2.根目录始终优先于根目录。有几种方法可以解决这个问题:

只需确保根目录实际上没有任何引用—将主域的基目录设置为另一个子目录,而不是根目录

或者,在域设置中充分利用
ApplicationBase
(即,更改根目录,而不是专用bin路径)

或者,使用
PrivateBinPathProbe
防止从根目录加载任何程序集


或者,设置
disallowApplicationBaseProbling
并实现
AppDomain.AssemblyResolve
事件-这使您可以手动控制域中的所有程序集解析。这可能是您真正想要的,不过我会将其与使基本域成为另一个“模块”结合起来。

谢谢,伙计。你的回答引发了更多的问题。首先,我使用了DisallowApplicationBaseProbling。我还必须解决.net依赖关系吗?比如说System.Net.Http。在这种情况下,是否需要手动解决这些问题。还有,我有两个相同依赖项的不同版本,比如log4net。根目录包含错误的版本,而AssemblyDirectory包含正确的版本。我是否会遇到异常,或者框架是否会重试并进一步查看,以确定我的数据库中是否有正确的版本AssembyDirectory@Tusker我认为您不需要手动解析GAC中的程序集,其中包括System.Net.Http。据我所知,程序集绑定算法不是回溯的,所以除非DLL在GAC中,否则它不会尝试加载不同的版本——它将失败;然而,我可能错了——测试起来应该很容易:)我终于做到了。我使用了第二个选项,将所有共享DLL放在root/Library中,并将此路径添加到应用程序配置中。所有包含独立程序集的域都将专用bin路径设置为搜索(root)\Library\AssemblyName\first和(root)\Library\second),从而使DLL的本地实例优先于共享实例。