diff --git a/NewLife.Core/Reflection/AssemblyX.cs b/NewLife.Core/Reflection/AssemblyX.cs index 0799f665a..975104518 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 String? Location 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 _Types; diff --git a/XUnitTest.Core/Reflection/AssemblyXTests.cs b/XUnitTest.Core/Reflection/AssemblyXTests.cs index 191287633..07dba0847 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 void GetCompileTime() Assert.Equal("2022-04-27 03:44:00".ToDateTime(), time.ToUniversalTime()); } } + + [Fact] + public void OnAssemblyResolve_ResourceAssembly_DontInitSetting() + { + var currentField = typeof(Config).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); + } + } }