添加ResolveEventHandler后GAC中的DllInGac.dll被忽略问题
针对.NET Framework程序集加载问题的解决方案
问题根因
注册AppDomain.CurrentDomain.AssemblyResolve事件后,CLR在加载程序集失败时会触发该事件。如果你的OurResolveEventHandler处理程序既没有返回目标程序集,也没有返回null,会导致CLR跳过默认的程序集查找流程(包括检查全局程序集缓存GAC),从而找不到原本存在于GAC中的DllInGac.dll。而提前实例化OtherClass时,CLR已经通过默认流程加载了GAC中的程序集,后续调用自然不会触发事件。
可行解决方案
1. 修改事件处理程序,未找到时返回null
让处理程序只负责你需要自定义加载的程序集,其他情况返回null,这样CLR会继续执行默认查找逻辑(包含GAC检查):
private static Assembly OurResolveEventHandler(object sender, ResolveEventArgs args) { // 仅处理特定的自定义程序集,比如本地私有目录中的DLL if (args.Name.StartsWith("YourCustomAssembly,")) { string assemblyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "YourCustomAssembly.dll"); return File.Exists(assemblyPath) ? Assembly.LoadFrom(assemblyPath) : null; } // 非自定义处理的程序集,返回null交由CLR默认逻辑处理 return null; }
2. 在事件处理程序中主动优先加载GAC程序集
通过Assembly.Load()方法(该方法会优先检查GAC)尝试加载目标程序集,失败后再执行自定义加载逻辑:
private static Assembly OurResolveEventHandler(object sender, ResolveEventArgs args) { try { // 优先使用CLR默认逻辑加载(包含GAC) return Assembly.Load(args.Name); } catch (FileNotFoundException) { // 自定义加载逻辑:加载本地私有目录中的程序集 var assemblyName = new AssemblyName(args.Name).Name; string localPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"{assemblyName}.dll"); return File.Exists(localPath) ? Assembly.LoadFrom(localPath) : null; } }
3. 临时注册事件(若场景允许)
如果仅少数程序集需要自定义加载,可临时注册事件,完成加载后立即取消注册,避免影响全局程序集加载流程:
// 临时注册事件 AppDomain.CurrentDomain.AssemblyResolve += OurResolveEventHandler; // 加载需要自定义处理的程序集 var customAssembly = Assembly.Load("YourCustomAssembly"); // 取消注册,恢复默认加载逻辑 AppDomain.CurrentDomain.AssemblyResolve -= OurResolveEventHandler;
内容的提问来源于stack exchange,提问作者dabark
相关产品推荐
相关产品推荐

