解决 .NET 7 在 Linux 上获取程序集的问题

方案

 1 /// <summary>
 2 /// 获取应用有效程序集
 3 /// </summary>
 4 /// <returns>IEnumerable<Assembly></returns>
 5 private static IEnumerable<Assembly> GetAssemblies()
 6 {
 7     // 需排除的程序集后缀
 8     var excludeAssemblyNames = new string[] {
 9         "Database.Migrations",
10     };
11 
12     // 获取当前应用程序域中的所有已加载程序集
13     var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
14     
15     // 尝试通过 DependencyContext 获取更多程序集(主要适用于发布为单文件的情况)
16     var dependencyContext = DependencyContext.Default;
17     if (dependencyContext != null)
18     {
19         var scanAssemblies = dependencyContext.CompileLibraries
20             .Where(lib => lib.Type == "project" ||
21                   (lib.Type == "package" && lib.Name.StartsWith("ASPNet.FrameworkLightAPI")) &&
22                   !excludeAssemblyNames.Any(j => lib.Name.EndsWith(j)));
23         
24         foreach (var lib in scanAssemblies)
25         {
26             try
27             {
28                 var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(lib.Name));
29                 if (!assemblies.Any(a => a.FullName == assembly.FullName))
30                 {
31                     assemblies.Add(assembly);
32                 }
33             }
34             catch
35             {
36                 // 忽略加载失败的程序集
37                 continue;
38             }
39         }
40     }
41 
42     return assemblies
43         .Where(a => !excludeAssemblyNames.Any(ex => a.FullName.Contains(ex)))
44         .Distinct();
45 }

 

替代方案(更可靠)

private static IEnumerable<Assembly> GetAssemblies()
{// 需排除的程序集后缀var excludeAssemblyNames = new string[] {"Database.Migrations",};// 获取入口程序集var entryAssembly = Assembly.GetEntryAssembly();var assemblies = new List<Assembly> { entryAssembly };// 获取所有引用的程序集var referencedAssemblies = entryAssembly.GetReferencedAssemblies();foreach (var assemblyName in referencedAssemblies){try{var assembly = Assembly.Load(assemblyName);if (!excludeAssemblyNames.Any(ex => assembly.FullName.Contains(ex))){assemblies.Add(assembly);}}catch{// 忽略加载失败的程序集continue;}}return assemblies.Distinct();
}