// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Runtime.Loader;
using SysReflection = System.Reflection.IntrospectionExtensions;
namespace Admin.NET.Core;
///
/// 反射帮助类
/// 提供程序集、类型、属性等反射操作的工具方法
///
public static class ReflectionHelper
{
#region 程序集
///
/// 获取应用程序的入口程序集
///
/// 入口程序集,如果无法确定则返回 null
public static Assembly? GetEntryAssembly()
{
return Assembly.GetEntryAssembly();
}
///
/// 获取入口程序集的名称
///
/// 程序集名称,如果无法获取则返回 null
public static string? GetEntryAssemblyName()
{
return GetEntryAssembly()?.GetName().Name;
}
///
/// 获取入口程序集的版本信息
///
/// 程序集版本,如果无法获取则返回 null
public static Version? GetEntryAssemblyVersion()
{
return GetEntryAssembly()?.GetName().Version;
}
///
/// 获取指定目录下的程序集文件路径
///
/// 要搜索的文件夹路径
/// 搜索选项(是否包含子目录)
/// 程序集文件路径集合(.dll 和 .exe 文件)
/// 当文件夹路径为空或 null 时
public static IEnumerable GetAssemblyFiles(string folderPath, SearchOption searchOption)
{
ArgumentException.ThrowIfNullOrWhiteSpace(folderPath);
return Directory
.EnumerateFiles(folderPath, "*.*", searchOption)
.Where(s => s.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) ||
s.EndsWith(".exe", StringComparison.OrdinalIgnoreCase));
}
///
/// 从指定目录加载所有程序集
///
/// 要搜索的文件夹路径
/// 搜索选项(是否包含子目录)
/// 加载的程序集列表
/// 当文件夹路径为空或 null 时
public static List LoadAssemblies(string folderPath, SearchOption searchOption)
{
ArgumentException.ThrowIfNullOrWhiteSpace(folderPath);
return [.. GetAssemblyFiles(folderPath, searchOption).Select(AssemblyLoadContext.Default.LoadFromAssemblyPath)];
}
///
/// 获取当前应用程序域中加载的所有程序集
///
/// 已加载的程序集集合
public static IEnumerable GetAllAssemblies()
{
return AssemblyLoadContext.Default.Assemblies;
}
///
/// 获取所有被引用的程序集(递归获取所有依赖项)
///
/// 是否跳过系统程序集(默认为 true)
/// 被引用的程序集集合
public static IEnumerable GetAllReferencedAssemblies(bool skipSystemAssemblies = true)
{
var rootAssembly = Assembly.GetEntryAssembly();
rootAssembly ??= Assembly.GetCallingAssembly();
HashSet returnAssemblies = new(new AssemblyEquality());
HashSet loadedAssemblies = [];
Queue assembliesToCheck = new();
assembliesToCheck.Enqueue(rootAssembly);
if (skipSystemAssemblies && IsSystemAssembly(rootAssembly))
{
if (IsValid(rootAssembly))
{
_ = returnAssemblies.Add(rootAssembly);
}
}
while (assembliesToCheck.Count != 0)
{
var assemblyToCheck = assembliesToCheck.Dequeue();
foreach (var reference in assemblyToCheck.GetReferencedAssemblies())
{
if (loadedAssemblies.Contains(reference.FullName))
{
continue;
}
var assembly = Assembly.Load(reference);
if (skipSystemAssemblies && IsSystemAssembly(assembly))
{
continue;
}
assembliesToCheck.Enqueue(assembly);
_ = loadedAssemblies.Add(reference.FullName);
if (IsValid(assembly))
{
_ = returnAssemblies.Add(assembly);
}
}
}
var asmsInBaseDir = Directory.EnumerateFiles(AppContext.BaseDirectory, "*.dll", new EnumerationOptions
{
RecurseSubdirectories = true
});
foreach (var assemblyPath in asmsInBaseDir)
{
if (!IsManagedAssembly(assemblyPath))
{
continue;
}
var asmName = AssemblyName.GetAssemblyName(assemblyPath);
// 如果程序集已经加载过了就不再加载
if (returnAssemblies.Any(x => AssemblyName.ReferenceMatchesDefinition(x.GetName(), asmName)))
{
continue;
}
if (skipSystemAssemblies && IsSystemAssembly(assemblyPath))
{
continue;
}
var asm = TryLoadAssembly(assemblyPath);
if (asm is null)
{
continue;
}
if (!IsValid(asm))
{
continue;
}
if (skipSystemAssemblies && IsSystemAssembly(asm))
{
continue;
}
_ = returnAssemblies.Add(asm);
}
return [.. returnAssemblies];
}
///
/// 获取符合条件名称的程序集
///
/// 前缀名
/// 后缀名
/// 包含名
///
public static IEnumerable GetEffectiveAssemblies(string prefix, string suffix, string contain)
{
ArgumentException.ThrowIfNullOrWhiteSpace(prefix);
ArgumentException.ThrowIfNullOrWhiteSpace(suffix);
ArgumentException.ThrowIfNullOrWhiteSpace(contain);
return GetAllAssemblies()
.Where(assembly => assembly.ManifestModule.Name.EndsWith(suffix, StringComparison.InvariantCultureIgnoreCase))
.Where(assembly => assembly.ManifestModule.Name.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
.Where(assembly => assembly.ManifestModule.Name.Contains(contain, StringComparison.InvariantCultureIgnoreCase))
.Distinct();
}
///
/// 获取符合条件前后缀名称的程序集
///
/// 前缀名
/// 后缀名
///
public static IEnumerable GetEffectivePatchAssemblies(string prefix, string suffix)
{
ArgumentException.ThrowIfNullOrWhiteSpace(prefix);
ArgumentException.ThrowIfNullOrWhiteSpace(suffix);
return GetAllAssemblies()
.Where(assembly => assembly.ManifestModule.Name.EndsWith(suffix, StringComparison.InvariantCultureIgnoreCase))
.Where(assembly => assembly.ManifestModule.Name.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
.Distinct();
}
///
/// 获取符合条件包含名称的程序集
///
/// 包含名
///
public static IEnumerable GetEffectiveCenterAssemblies(string contain)
{
ArgumentException.ThrowIfNullOrWhiteSpace(contain);
return GetAllAssemblies()
.Where(assembly => assembly.ManifestModule.Name.Contains(contain, StringComparison.InvariantCultureIgnoreCase))
.Distinct();
}
///
/// 获取框架程序集
///
///
public static IEnumerable GetAdminNETAssemblies()
{
return GetEffectivePatchAssemblies("Admin.NET", "dll");
}
///
/// 获取应用程序集
///
///
public static IEnumerable GetApplicationAssemblies()
{
return GetEffectiveCenterAssemblies("Application");
}
///
/// 获取框架应用程序集
///
///
public static IEnumerable GetAdminNETApplicationAssemblies()
{
return GetEffectiveAssemblies("Admin.NET", "dll", "Application");
}
#endregion 程序集
#region 程序集类
///
/// 获取所有已加载程序集中的所有类型
///
/// 所有类型的集合
public static IEnumerable GetAllTypes()
{
return GetAllAssemblies()
.SelectMany(GetAllTypes)
.Distinct();
}
///
/// 获取指定程序集中的所有类型(安全获取,处理加载异常)
///
/// 目标程序集
/// 程序集中的类型集合
/// 当程序集为 null 时
public static IEnumerable GetAllTypes(Assembly assembly)
{
ArgumentNullException.ThrowIfNull(assembly);
try
{
return assembly.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
return ex.Types.Where(type => type != null)!;
}
}
///
/// 获取框架框架程序集中的所有类型
///
/// 框架框架类型集合
public static IEnumerable GetAdminNETTypes()
{
return GetAdminNETAssemblies()
.SelectMany(GetAllTypes)
.Distinct();
}
///
/// 获取应用程序集中的所有类型
///
/// 应用程序类型集合
public static IEnumerable GetApplicationTypes()
{
return GetApplicationAssemblies()
.SelectMany(GetAllTypes)
.Distinct();
}
///
/// 获取框架应用程序集中的所有类型
///
/// 框架应用程序类型集合
public static IEnumerable GetAdminNETApplicationTypes()
{
return GetAdminNETApplicationAssemblies()
.SelectMany(GetAllTypes)
.Distinct();
}
#endregion 程序集类
#region 类型
///
/// 检查给定类型是否实现或继承了指定的泛型类型
///
/// 要检查的类型
/// 泛型类型定义
/// 如果给定类型实现或继承了泛型类型则返回 true,否则返回 false
public static bool IsAssignableToGenericType(Type givenType, Type genericType)
{
ArgumentNullException.ThrowIfNull(givenType);
ArgumentNullException.ThrowIfNull(genericType);
var givenTypeInfo = SysReflection.GetTypeInfo(givenType);
if (givenTypeInfo.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
{
return true;
}
foreach (var interfaceType in givenTypeInfo.GetInterfaces())
{
if (SysReflection.GetTypeInfo(interfaceType).IsGenericType && interfaceType.GetGenericTypeDefinition() == genericType)
{
return true;
}
}
return givenTypeInfo.BaseType != null && IsAssignableToGenericType(givenTypeInfo.BaseType, genericType);
}
///
/// 获取给定类型实现的所有泛型类型
///
/// 要检查的类型
/// 泛型类型定义
/// 实现的泛型类型列表
public static List GetImplementedGenericTypes(Type givenType, Type genericType)
{
ArgumentNullException.ThrowIfNull(givenType);
ArgumentNullException.ThrowIfNull(genericType);
var result = new List();
AddImplementedGenericTypes(result, givenType, genericType);
return result;
}
///
/// 尝试获取类成员及其声明类型上定义的单个特性,包括继承的特性
/// 如果未找到则返回默认值
///
/// 特性类型
/// 成员信息
/// 默认值(默认为 null)
/// 是否从基类继承特性
/// 找到的特性实例或默认值
public static TAttribute? GetSingleAttributeOrDefault(MemberInfo memberInfo, TAttribute? defaultValue = default, bool inherit = true)
where TAttribute : Attribute
{
ArgumentNullException.ThrowIfNull(memberInfo);
// 使用 GetCustomAttributes 方法获取特性
return memberInfo.IsDefined(typeof(TAttribute), inherit)
? memberInfo.GetCustomAttributes(typeof(TAttribute), inherit).Cast().First()
: defaultValue;
}
///
/// 尝试获取类成员或其声明类型上定义的单个特性,包括继承的特性
/// 如果未找到则返回默认值
///
/// 特性类型
/// 成员信息
/// 默认值(默认为 null)
/// 是否从基类继承特性
/// 找到的特性实例或默认值
public static TAttribute? GetSingleAttributeOfMemberOrDeclaringTypeOrDefault(MemberInfo memberInfo, TAttribute? defaultValue = default, bool inherit = true)
where TAttribute : class
{
ArgumentNullException.ThrowIfNull(memberInfo);
return memberInfo.GetCustomAttributes(inherit).OfType().FirstOrDefault()
?? SysReflection.GetTypeInfo(memberInfo.DeclaringType).GetCustomAttributes(inherit).OfType().FirstOrDefault()
?? defaultValue;
}
///
/// 获取类成员及其声明类型上定义的所有特性,包括继承的特性
///
/// 特性类型
/// 成员信息
/// 是否从基类继承特性
/// 特性集合
public static IEnumerable GetAttributesOfMemberOrDeclaringType(MemberInfo memberInfo, bool inherit = true)
where TAttribute : class
{
ArgumentNullException.ThrowIfNull(memberInfo);
var customAttributes = memberInfo.GetCustomAttributes(inherit).OfType();
var declaringTypeCustomAttributes =
SysReflection.GetTypeInfo(memberInfo.DeclaringType).GetCustomAttributes(inherit).OfType();
return declaringTypeCustomAttributes != null
? customAttributes.Concat(declaringTypeCustomAttributes).Distinct()
: customAttributes;
}
///
/// 通过完整属性路径从给定对象获取属性值
///
/// 目标对象
/// 对象类型
/// 属性路径(支持嵌套属性,用点分隔)
/// 属性值,如果属性不存在则返回 null
public static object? GetValueByPath(object obj, Type objectType, string propertyPath)
{
ArgumentNullException.ThrowIfNull(obj);
ArgumentNullException.ThrowIfNull(objectType);
ArgumentException.ThrowIfNullOrWhiteSpace(propertyPath);
var value = obj;
var currentType = objectType;
var objectPath = currentType.FullName;
var absolutePropertyPath = propertyPath;
if (objectPath != null && absolutePropertyPath.StartsWith(objectPath))
{
absolutePropertyPath = absolutePropertyPath.Replace(objectPath + ".", "");
}
foreach (var propertyName in absolutePropertyPath.Split('.'))
{
var property = currentType.GetProperty(propertyName);
if (property != null)
{
if (value != null)
{
value = property.GetValue(value, null);
}
currentType = property.PropertyType;
}
else
{
value = null;
break;
}
}
return value;
}
///
/// 递归获取指定类型中的所有公共常量值(包括基类型)
///
/// 目标类型
/// 常量值数组
public static string[] GetPublicConstantsRecursively(Type type)
{
ArgumentNullException.ThrowIfNull(type);
const int MaxRecursiveParameterValidationDepth = 8;
var publicConstants = new List();
static void Recursively(List constants, Type targetType, int currentDepth)
{
if (currentDepth > MaxRecursiveParameterValidationDepth)
{
return;
}
constants.AddRange(targetType.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
.Where(x => x.IsLiteral && !x.IsInitOnly)
.Select(x => x.GetValue(null)!.ToString()!));
var nestedTypes = targetType.GetNestedTypes(BindingFlags.Public);
foreach (var nestedType in nestedTypes)
{
Recursively(constants, nestedType, currentDepth + 1);
}
}
Recursively(publicConstants, type, 1);
return [.. publicConstants];
}
///
/// 通过完整属性路径设置给定对象的属性值
///
/// 目标对象
/// 对象类型
/// 属性路径(支持嵌套属性,用点分隔)
/// 要设置的值
internal static void SetValueByPath(object obj, Type objectType, string propertyPath, object value)
{
ArgumentNullException.ThrowIfNull(obj);
ArgumentNullException.ThrowIfNull(objectType);
ArgumentException.ThrowIfNullOrWhiteSpace(propertyPath);
var currentType = objectType;
PropertyInfo property;
var objectPath = currentType.FullName!;
var absolutePropertyPath = propertyPath;
if (absolutePropertyPath.StartsWith(objectPath))
{
absolutePropertyPath = absolutePropertyPath.Replace(objectPath + ".", "");
}
var properties = absolutePropertyPath.Split('.');
if (properties.Length == 1)
{
property = objectType.GetProperty(properties.First())!;
property.SetValue(obj, value);
return;
}
for (var i = 0; i < properties.Length - 1; i++)
{
property = currentType.GetProperty(properties[i])!;
obj = property.GetValue(obj, null)!;
currentType = property.PropertyType;
}
property = currentType.GetProperty(properties.Last())!;
property.SetValue(obj, value);
}
///
/// 添加实现的泛型类型到结果列表
///
/// 结果列表
/// 给定类型
/// 泛型类型
private static void AddImplementedGenericTypes(List result, Type givenType, Type genericType)
{
var givenTypeInfo = SysReflection.GetTypeInfo(givenType);
if (givenTypeInfo.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
{
result.AddIfNotContains(givenType);
}
foreach (var interfaceType in givenTypeInfo.GetInterfaces())
{
if (SysReflection.GetTypeInfo(interfaceType).IsGenericType && interfaceType.GetGenericTypeDefinition() == genericType)
{
result.AddIfNotContains(interfaceType);
}
}
if (givenTypeInfo.BaseType == null)
{
return;
}
AddImplementedGenericTypes(result, givenTypeInfo.BaseType, genericType);
}
#endregion 类型
#region 获取包含有某特性的类
///
/// 获取包含有某特性的类
/// 第一种实现
///
///
///
public static IEnumerable GetContainsAttributeTypes()
where TAttribute : Attribute
{
return GetAllTypes()
.Where(e => e.CustomAttributes.Any(g => g.AttributeType == typeof(TAttribute)));
}
///
/// 获取包含有某特性的类
/// 第二种实现
///
///
///
public static IEnumerable GetContainsAttributeTypes(Attribute attribute)
{
return GetAllTypes()
.Where(e => e.CustomAttributes.Any(g => g.AttributeType == attribute.GetType()));
}
#endregion 获取包含有某特性的类
#region 获取不包含有某特性的类
///
/// 获取不包含有某特性的类
/// 第一种实现
///
///
///
public static IEnumerable GetFilterAttributeTypes()
where TAttribute : Attribute
{
return GetAllTypes()
.Where(e => e.CustomAttributes.All(g => g.AttributeType != typeof(TAttribute)));
}
///
/// 获取包含有某特性的类
/// 第二种实现
///
///
///
public static IEnumerable GetFilterAttributeTypes(Attribute attribute)
{
return GetAllTypes()
.Where(e => e.CustomAttributes.All(g => g.AttributeType != attribute.GetType()));
}
#endregion 获取不包含有某特性的类
#region 获取某类的子类(非抽象类)
///
/// 获取某类的子类(非抽象类)
/// 第一种实现
///
///
///
public static IEnumerable GetSubClasses()
where T : class
{
return GetAllTypes()
.Where(t => t is { IsInterface: false, IsClass: true, IsAbstract: false })
.Where(t => typeof(T).IsAssignableFrom(t));
}
///
/// 获取某类的子类(非抽象类)
/// 第二种实现
///
///
///
public static IEnumerable GetSubClasses(Type type)
{
return GetAllTypes()
.Where(t => t is { IsInterface: false, IsClass: true, IsAbstract: false })
.Where(type.IsAssignableFrom);
}
///
/// 获取某泛型接口的子类(非抽象类)
///
///
///
public static IEnumerable GetSubClassesByGenericInterface(Type interfaceType)
{
return [.. GetAllTypes()
.Where(type => type is { IsInterface: false, IsClass: true, IsAbstract: false }
&& type.GetInterfaces().Any(i => i.IsGenericType
&& i.GetGenericTypeDefinition() == interfaceType))];
}
#endregion 获取某类的子类(非抽象类)
#region 获取继承自某类的包含有某特性的接口、类的子类(非抽象类)
///
/// 获取继承自某类的包含有某特性的接口、类的子类(非抽象类)
/// 第一种实现
///
///
///
///
public static IEnumerable GetContainsAttributeSubClasses()
where T : class
where TAttribute : Attribute
{
return GetSubClasses().Intersect(GetContainsAttributeTypes());
}
///
/// 获取继承自某类的包含有某特性的接口、类的子类(非抽象类)
/// 第二种实现
///
///
///
///
public static IEnumerable GetContainsAttributeSubClasses(Type type)
where TAttribute : Attribute
{
return GetSubClasses(type).Intersect(GetContainsAttributeTypes());
}
#endregion 获取继承自某类的包含有某特性的接口、类的子类(非抽象类)
#region 获取继承自某类的不包含有某特性的接口、类的子类(非抽象类)
///
/// 获取继承自某类的不包含有某特性的接口、类的子类(非抽象类)
/// 第一种实现
///
///
///
///
public static IEnumerable GetFilterAttributeSubClass()
where T : class
where TAttribute : Attribute
{
return GetSubClasses().Intersect(GetFilterAttributeTypes());
}
///
/// 获取继承自某类的不包含有某特性的接口、类的子类(非抽象类)
/// 第二种实现
///
///
///
///
public static IEnumerable GetFilterAttributeSubClass(Type type)
where TAttribute : Attribute
{
return GetSubClasses(type).Intersect(GetFilterAttributeTypes());
}
#endregion 获取继承自某类的不包含有某特性的接口、类的子类(非抽象类)
#region 程序集依赖包
///
/// 获取当前应用程序的 NuGet 程序包依赖项
///
/// 前缀名
/// NuGet 包信息列表
public static List GetNuGetPackages(string prefix)
{
var nugetPackages = new Dictionary();
// 获取当前应用所有程序集
var assemblies = GetEffectivePatchAssemblies(prefix, "dll");
// 查找被引用程序集中的 NuGet 库依赖项
foreach (var assembly in assemblies)
{
try
{
var referencedAssemblies = assembly.GetReferencedAssemblies()
.Where(s => !s.FullName.StartsWith("Microsoft", StringComparison.OrdinalIgnoreCase) &&
!s.FullName.StartsWith("System", StringComparison.OrdinalIgnoreCase))
.Where(s => !string.IsNullOrEmpty(s.Name) && s.Version != null);
foreach (var referencedAssembly in referencedAssemblies)
{
// 检查引用的程序集是否来自 NuGet
if (string.IsNullOrEmpty(referencedAssembly.Name) || referencedAssembly.Version == null)
{
continue;
}
var packageName = referencedAssembly.Name;
var packageVersion = referencedAssembly.Version.ToString();
// 避免重复添加相同的 NuGet 包,保留版本更高的
if (!nugetPackages.TryGetValue(packageName, out var value))
{
nugetPackages[packageName] = new NuGetPackage
{
PackageName = packageName,
PackageVersion = packageVersion
};
}
else
{
var existingVersion = Version.Parse(value.PackageVersion);
var currentVersion = referencedAssembly.Version;
if (currentVersion > existingVersion)
{
nugetPackages[packageName] = new NuGetPackage
{
PackageName = packageName,
PackageVersion = packageVersion
};
}
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"Error processing assembly {assembly.FullName}: {ex.Message}");
}
}
return [.. nugetPackages.Values.OrderBy(p => p.PackageName)];
}
#endregion 程序集依赖包
#region 私有方法
///
/// 判断程序集是否为系统程序集(如微软官方程序集)
///
/// 要检查的程序集
/// 如果是系统程序集则返回 true,否则返回 false
private static bool IsSystemAssembly(Assembly assembly)
{
ArgumentNullException.ThrowIfNull(assembly);
var asmCompanyAttr = assembly.GetCustomAttribute();
if (asmCompanyAttr is null)
{
return false;
}
var companyName = asmCompanyAttr.Company;
return companyName.Contains("Microsoft", StringComparison.OrdinalIgnoreCase);
}
///
/// 通过程序集路径判断是否为系统程序集
///
/// 程序集文件路径
/// 如果是系统程序集则返回 true,否则返回 false
private static bool IsSystemAssembly(string assemblyPath)
{
ArgumentException.ThrowIfNullOrWhiteSpace(assemblyPath);
try
{
var assembly = Assembly.LoadFrom(assemblyPath);
return IsSystemAssembly(assembly);
}
catch
{
return false;
}
}
///
/// 判断程序集是否有效(能否正常加载类型)
///
/// 要验证的程序集
/// 如果程序集有效则返回 true,否则返回 false
private static bool IsValid(Assembly assembly)
{
ArgumentNullException.ThrowIfNull(assembly);
try
{
_ = assembly.GetTypes();
_ = assembly.DefinedTypes.ToList();
return true;
}
catch (ReflectionTypeLoadException)
{
return false;
}
catch (Exception)
{
return false;
}
}
///
/// 判断指定文件是否为托管程序集
///
/// 程序集文件路径
/// 如果是托管程序集则返回 true,否则返回 false
private static bool IsManagedAssembly(string file)
{
ArgumentException.ThrowIfNullOrWhiteSpace(file);
try
{
using var fs = File.OpenRead(file);
using PEReader peReader = new(fs);
return peReader.HasMetadata && peReader.GetMetadataReader().IsAssembly;
}
catch
{
return false;
}
}
///
/// 安全地尝试加载程序集,处理各种加载异常
///
/// 程序集文件路径
/// 成功加载的程序集,失败则返回 null
private static Assembly? TryLoadAssembly(string assemblyPath)
{
ArgumentException.ThrowIfNullOrWhiteSpace(assemblyPath);
if (!File.Exists(assemblyPath))
{
return null;
}
Assembly? assembly = null;
try
{
var assemblyName = AssemblyName.GetAssemblyName(assemblyPath);
assembly = Assembly.Load(assemblyName);
}
catch (BadImageFormatException ex)
{
Debug.WriteLine($"BadImageFormatException loading assembly {assemblyPath}: {ex.Message}");
}
catch (FileLoadException ex)
{
Debug.WriteLine($"FileLoadException loading assembly {assemblyPath}: {ex.Message}");
}
catch (Exception ex)
{
Debug.WriteLine($"Exception loading assembly {assemblyPath}: {ex.Message}");
}
if (assembly is not null)
{
return assembly;
}
try
{
assembly = Assembly.LoadFile(assemblyPath);
}
catch (BadImageFormatException ex)
{
Debug.WriteLine($"BadImageFormatException loading file {assemblyPath}: {ex.Message}");
}
catch (FileLoadException ex)
{
Debug.WriteLine($"FileLoadException loading file {assemblyPath}: {ex.Message}");
}
catch (Exception ex)
{
Debug.WriteLine($"Exception loading file {assemblyPath}: {ex.Message}");
}
return assembly;
}
#endregion 私有方法
}
///
/// 程序集相等性比较器
/// 用于比较两个程序集是否相等,基于程序集名称进行匹配
///
internal class AssemblyEquality : EqualityComparer
{
///
/// 比较两个程序集是否相等
///
/// 第一个程序集
/// 第二个程序集
/// 如果两个程序集相等则返回 true,否则返回 false
public override bool Equals(Assembly? x, Assembly? y)
{
return (x is null && y is null) ||
(x is not null && y is not null &&
AssemblyName.ReferenceMatchesDefinition(x.GetName(), y.GetName()));
}
///
/// 获取程序集的哈希代码
///
/// 程序集对象
/// 程序集的哈希代码
/// 当程序集为 null 时
public override int GetHashCode(Assembly obj)
{
ArgumentNullException.ThrowIfNull(obj);
return obj.GetName().FullName.GetHashCode(StringComparison.OrdinalIgnoreCase);
}
}
///
/// NuGet 程序包信息记录
/// 表示一个 NuGet 包的基本信息,包括包名和版本
///
public record NuGetPackage
{
///
/// NuGet 包名称
///
public string PackageName { get; init; } = string.Empty;
///
/// NuGet 包版本号
///
public string PackageVersion { get; init; } = string.Empty;
///
/// 获取包的完整标识符
///
/// 格式为 "PackageName@PackageVersion" 的字符串
public override string ToString()
{
return $"{PackageName}@{PackageVersion}";
}
}