Merge branch 'master' of https://github.com/NewLifeX/X石头 authored at 2026-04-27 01:13:54
diff --git a/NewLife.Core/Reflection/AssemblyX.cs b/NewLife.Core/Reflection/AssemblyX.cs
index 0799f66..9751045 100644
--- a/NewLife.Core/Reflection/AssemblyX.cs
+++ b/NewLife.Core/Reflection/AssemblyX.cs
@@ -1,7 +1,8 @@
-using System.Collections.Concurrent;
-using System.ComponentModel;
-using System.Diagnostics.CodeAnalysis;
-using System.Reflection;
+using System.Collections.Concurrent;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Reflection;
using NewLife.Collections;
using NewLife.Log;
@@ -104,44 +105,61 @@ public class AssemblyX
return cache.GetOrAdd(asm, key => new AssemblyX(key));
}
- static AssemblyX()
- {
- //AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += OnReflectionOnlyAssemblyResolve;
- AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
- }
-
- private static Assembly? OnAssemblyResolve(Object? sender, ResolveEventArgs args)
- {
- var flag = XTrace.Log.Level <= LogLevel.Debug;
- if (flag) XTrace.WriteLine("[{0}]请求加载[{1}]", args.RequestingAssembly?.FullName, args.Name);
- //if (!flag) return null;
-
- try
- {
- // 尝试在请求者所在目录加载
- var file = args.RequestingAssembly?.Location;
- if (!file.IsNullOrEmpty() && !args.Name.IsNullOrEmpty())
- {
- var name = args.Name;
- var p = name.IndexOf(',');
- if (p > 0) name = name[..p];
-
- file = Path.GetDirectoryName(file).CombinePath(name + ".dll");
- if (File.Exists(file)) return Assembly.LoadFrom(file);
- }
-
- // 辅助解析程序集。程序集加载过程中,被依赖程序集未能解析时,是否协助解析,默认false
- if (Setting.Current.AssemblyResolve && !args.Name.IsNullOrEmpty())
- return OnResolve(args.Name);
- }
- catch (Exception ex)
- {
- XTrace.WriteException(ex);
- }
-
- return null;
- }
- #endregion
+ static AssemblyX()
+ {
+ //AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += OnReflectionOnlyAssemblyResolve;
+ AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
+ }
+
+ [ThreadStatic]
+ private static Int32 _resolving;
+
+ private static Assembly? OnAssemblyResolve(Object? sender, ResolveEventArgs args)
+ {
+ if (_resolving > 0) return null;
+
+ var name = args.Name;
+ if (name.IsNullOrEmpty() || IsSatelliteResourceAssembly(name)) return null;
+
+ _resolving++;
+ try
+ {
+ // 尝试在请求者所在目录加载
+ var file = args.RequestingAssembly?.Location;
+ if (!file.IsNullOrEmpty())
+ {
+ var assemblyName = name;
+ var p = assemblyName.IndexOf(',');
+ if (p > 0) assemblyName = assemblyName[..p];
+
+ file = Path.GetDirectoryName(file).CombinePath(assemblyName + ".dll");
+ if (File.Exists(file)) return Assembly.LoadFrom(file);
+ }
+
+ // 辅助解析程序集。程序集加载过程中,被依赖程序集未能解析时,是否协助解析,默认false
+ if (Setting.Current.AssemblyResolve) return OnResolve(name);
+ }
+ catch (Exception ex)
+ {
+ Trace.WriteLine(ex);
+ return null;
+ }
+ finally
+ {
+ _resolving--;
+ }
+
+ return null;
+ }
+
+ private static Boolean IsSatelliteResourceAssembly(String name)
+ {
+ var p = name.IndexOf(',');
+ if (p > 0) name = name[..p];
+
+ return name.EndsWith(".resources", StringComparison.OrdinalIgnoreCase);
+ }
+ #endregion
#region 扩展属性
//private IEnumerable<Type> _Types;
diff --git a/XUnitTest.Core/Reflection/AssemblyXTests.cs b/XUnitTest.Core/Reflection/AssemblyXTests.cs
index 1912876..07dba08 100644
--- a/XUnitTest.Core/Reflection/AssemblyXTests.cs
+++ b/XUnitTest.Core/Reflection/AssemblyXTests.cs
@@ -1,4 +1,7 @@
-using NewLife;
+using System.IO;
+using System.Reflection;
+using NewLife;
+using NewLife.Configuration;
using NewLife.Reflection;
using Xunit;
@@ -25,4 +28,30 @@ public class AssemblyXTests
Assert.Equal("2022-04-27 03:44:00".ToDateTime(), time.ToUniversalTime());
}
}
+
+ [Fact]
+ public void OnAssemblyResolve_ResourceAssembly_DontInitSetting()
+ {
+ var currentField = typeof(Config<Setting>).GetField("_Current", BindingFlags.NonPublic | BindingFlags.Static);
+ Assert.NotNull(currentField);
+
+ var old = currentField.GetValue(null);
+ try
+ {
+ currentField.SetValue(null, null);
+
+ var method = typeof(AssemblyX).GetMethod("OnAssemblyResolve", BindingFlags.NonPublic | BindingFlags.Static);
+ Assert.NotNull(method);
+
+ var args = new ResolveEventArgs("System.IO.FileSystem.Watcher.resources, Version=8.0.0.0, Culture=zh-CN, PublicKeyToken=b03f5f7f11d50a3a", typeof(FileSystemWatcher).Assembly);
+ var rs = method.Invoke(null, [null, args]);
+
+ Assert.Null(rs);
+ Assert.Null(currentField.GetValue(null));
+ }
+ finally
+ {
+ currentField.SetValue(null, old);
+ }
+ }
}