11using System ;
2+ using System . Collections . Generic ;
3+ using System . IO ;
24using System . Linq ;
35using System . Reflection ;
46using Microsoft . Extensions . DependencyInjection ;
@@ -19,43 +21,134 @@ public static IServiceCollection AddTurboMapper(
1921 {
2022 var mapper = new Mapper ( ) ;
2123
22- // Get all loaded assemblies in the AppDomain
23- var loadedAssemblies = AppDomain . CurrentDomain . GetAssemblies ( ) ;
24+ // Try to discover and register mapping modules using multiple strategies
25+ DiscoverAndRegisterMappingModules ( mapper ) ;
2426
25- // Discover and register mapping modules from all assemblies
26- foreach ( var assembly in loadedAssemblies )
27+ return mapper ;
28+ } ) ;
29+
30+ return services ;
31+ }
32+
33+ private static void DiscoverAndRegisterMappingModules ( Mapper mapper )
34+ {
35+ // Strategy 1: Get all currently loaded assemblies
36+ var loadedAssemblies = new HashSet < Assembly > ( ) ;
37+
38+ try
39+ {
40+ foreach ( var assembly in AppDomain . CurrentDomain . GetAssemblies ( ) )
2741 {
28- // Skip assemblies that might not be accessible
2942 if ( ! assembly . IsDynamic && ! assembly . GlobalAssemblyCache )
43+ {
44+ loadedAssemblies . Add ( assembly ) ;
45+ }
46+ }
47+ }
48+ catch
49+ {
50+ // If we can't access the AppDomain assemblies, continue with empty set
51+ }
52+
53+ // Strategy 2: Add important assemblies that might not be loaded yet
54+ try
55+ {
56+ var entryAssembly = Assembly . GetEntryAssembly ( ) ;
57+ if ( entryAssembly != null && ! loadedAssemblies . Contains ( entryAssembly ) )
58+ {
59+ loadedAssemblies . Add ( entryAssembly ) ;
60+ }
61+ }
62+ catch
63+ {
64+ // Continue if entry assembly can't be accessed
65+ }
66+
67+ try
68+ {
69+ var callingAssembly = Assembly . GetCallingAssembly ( ) ;
70+ if ( callingAssembly != null && ! loadedAssemblies . Contains ( callingAssembly ) )
71+ {
72+ loadedAssemblies . Add ( callingAssembly ) ;
73+ }
74+ }
75+ catch
76+ {
77+ // Continue if calling assembly can't be accessed
78+ }
79+
80+ try
81+ {
82+ var executingAssembly = Assembly . GetExecutingAssembly ( ) ;
83+ if ( executingAssembly != null && ! loadedAssemblies . Contains ( executingAssembly ) )
84+ {
85+ loadedAssemblies . Add ( executingAssembly ) ;
86+ }
87+ }
88+ catch
89+ {
90+ // Continue if executing assembly can't be accessed
91+ }
92+
93+ // Process all discovered assemblies
94+ foreach ( var assembly in loadedAssemblies )
95+ {
96+ try
97+ {
98+ var mappingTypes = GetMappingTypesFromAssembly ( assembly ) ;
99+ foreach ( var type in mappingTypes )
30100 {
31101 try
32102 {
33- var mappingModules = assembly . GetTypes ( )
34- . Where ( t => t . IsClass && ! t . IsAbstract && typeof ( IMappingModule ) . IsAssignableFrom ( t ) )
35- . Select ( t => Activator . CreateInstance ( t ) as IMappingModule ) ;
36-
37- foreach ( var module in mappingModules )
103+ var module = Activator . CreateInstance ( type ) as IMappingModule ;
104+ if ( module != null )
38105 {
39106 module . CreateMap ( mapper ) ;
40107 }
41108 }
42- catch ( ReflectionTypeLoadException )
109+ catch
43110 {
44- // Skip assemblies that can't be loaded
45- continue ;
46- }
47- catch ( Exception )
48- {
49- // Skip assemblies that cause other errors
111+ // Skip modules that can't be instantiated
50112 continue ;
51113 }
52114 }
53115 }
54-
55- return mapper ;
56- } ) ;
57-
58- return services ;
116+ catch ( Exception )
117+ {
118+ // Skip assemblies that cause errors during processing
119+ continue ;
120+ }
121+ }
122+ }
123+
124+ private static List < Type > GetMappingTypesFromAssembly ( Assembly assembly )
125+ {
126+ try
127+ {
128+ if ( assembly . IsDynamic || assembly . GlobalAssemblyCache )
129+ {
130+ return new List < Type > ( ) ;
131+ }
132+
133+ return assembly . GetTypes ( )
134+ . Where ( t => t . IsClass && ! t . IsAbstract && typeof ( IMappingModule ) . IsAssignableFrom ( t ) )
135+ . ToList ( ) ;
136+ }
137+ catch ( ReflectionTypeLoadException ex )
138+ {
139+ // If types can't be loaded, try to work with the ones that loaded
140+ var types = new List < Type > ( ) ;
141+ if ( ex . Types != null )
142+ {
143+ types = ex . Types . Where ( t => t != null && ! t . IsAbstract && typeof ( IMappingModule ) . IsAssignableFrom ( t ) ) . ToList ( ) ;
144+ }
145+ return types ;
146+ }
147+ catch ( Exception )
148+ {
149+ // For any other error, return an empty list
150+ return new List < Type > ( ) ;
151+ }
59152 }
60153 }
61154}
0 commit comments