1- using Snowberry . Mediator . Abstractions ;
1+ using System . Diagnostics . CodeAnalysis ;
2+ using System . Reflection ;
3+ using Snowberry . Mediator . Abstractions ;
24using Snowberry . Mediator . Abstractions . Handler ;
35using Snowberry . Mediator . Abstractions . Pipeline ;
46using Snowberry . Mediator . DependencyInjection . Shared . Contracts ;
@@ -14,106 +16,143 @@ namespace Snowberry.Mediator.DependencyInjection.Shared;
1416/// </summary>
1517public static class DependencyInjectionHelper
1618{
19+ public delegate void CustomAddCallbackDelegate (
20+ IServiceContext serviceContext ,
21+ MediatorOptions options ,
22+ RegistrationServiceLifetime serviceLifetime ,
23+ HandlerCollection handlerCollection ,
24+ bool append ) ;
25+
1726 /// <summary>
1827 /// Adds Mediator services to the specified service context.
1928 /// </summary>
29+ /// <remarks>This variant ignores the <see cref="MediatorOptions.Assemblies"/> option to be more compatible with AOT scenarios.</remarks>
2030 /// <param name="serviceContext">The service context.</param>
2131 /// <param name="options">The options.</param>
2232 /// <param name="serviceLifetime">The service lifetime.</param>
2333 /// <param name="append">Whether to append to existing registrations or replace them.</param>
24- public static void AddSnowberryMediator (
34+ /// <param name="customCallback">A custom callback to execute at the start during registration.</param>
35+ [ RequiresDynamicCode ( "Creating generic handler types at runtime requires dynamic code. Use explicit handler registration for AOT compatibility." ) ]
36+ public static void AddSnowberryMediatorNoScan (
2537 IServiceContext serviceContext ,
2638 MediatorOptions options ,
2739 RegistrationServiceLifetime serviceLifetime ,
28- bool append )
40+ bool append ,
41+ CustomAddCallbackDelegate ? customCallback )
2942 {
3043 if ( ! append || ! serviceContext . IsServiceRegistered < IMediator > ( ) )
3144 serviceContext . TryRegister ( typeof ( IMediator ) , typeof ( Mediator ) , serviceLifetime ) ;
3245
33- var allHandlers = new List < RequestHandlerInfo > ( ) ;
34- var allStreamHandlers = new List < StreamRequestHandlerInfo > ( ) ;
35- var allPipelineBehaviorHandlers = new List < PipelineBehaviorHandlerInfo > ( ) ;
36- var allStreamPipelineBehaviorHandlers = new List < StreamPipelineBehaviorHandlerInfo > ( ) ;
37- var allNotificationHandlers = new List < NotificationHandlerInfo > ( ) ;
38-
39- if ( options . Assemblies != null && options . Assemblies . Count > 0 )
40- {
41- for ( int i = 0 ; i < options . Assemblies . Count ; i ++ )
42- {
43- var assembly = options . Assemblies [ i ] ;
44-
45- var scanResult = MediatorAssemblyHelper . ScanAssembly ( assembly ) ;
46-
47- if ( scanResult . RequestHandlerTypes != null )
48- for ( int j = 0 ; j < scanResult . RequestHandlerTypes . Count ; j ++ )
49- allHandlers . Add ( scanResult . RequestHandlerTypes [ j ] ) ;
50-
51- if ( scanResult . StreamRequestHandlerTypes != null )
52- for ( int j = 0 ; j < scanResult . StreamRequestHandlerTypes . Count ; j ++ )
53- allStreamHandlers . Add ( scanResult . StreamRequestHandlerTypes [ j ] ) ;
46+ var handlerCollection = new HandlerCollection ( ) ;
5447
55- if ( options . RegisterPipelineBehaviors && options . ScanPipelineBehaviors && scanResult . PipelineBehaviorTypes != null )
56- for ( int j = 0 ; j < scanResult . PipelineBehaviorTypes . Count ; j ++ )
57- allPipelineBehaviorHandlers . Add ( scanResult . PipelineBehaviorTypes [ j ] ) ;
58-
59- if ( options . RegisterStreamPipelineBehaviors && options . ScanStreamPipelineBehaviors && scanResult . StreamPipelineBehaviorTypes != null )
60- for ( int j = 0 ; j < scanResult . StreamPipelineBehaviorTypes . Count ; j ++ )
61- allStreamPipelineBehaviorHandlers . Add ( scanResult . StreamPipelineBehaviorTypes [ j ] ) ;
62-
63- if ( options . RegisterNotificationHandlers && options . ScanNotificationHandlers && scanResult . NotificationHandlerTypes != null )
64- for ( int j = 0 ; j < scanResult . NotificationHandlerTypes . Count ; j ++ )
65- allNotificationHandlers . Add ( scanResult . NotificationHandlerTypes [ j ] ) ;
66- }
67- }
48+ customCallback ? . Invoke ( serviceContext , options , serviceLifetime , handlerCollection , append ) ;
6849
6950 var pipelineBehaviorType = typeof ( IPipelineBehavior < , > ) ;
7051 var streamPipelineBehaviorType = typeof ( IStreamPipelineBehavior < , > ) ;
7152 var requestHandlerType = typeof ( IRequestHandler < , > ) ;
7253 var streamRequestHandlerType = typeof ( IStreamRequestHandler < , > ) ;
7354
7455 if ( options . PipelineBehaviorTypes != null && options . RegisterPipelineBehaviors )
75- MediatorAssemblyHelper . ParseHandlerInfo ( pipelineBehaviorType , options . PipelineBehaviorTypes , allPipelineBehaviorHandlers ) ;
56+ MediatorAssemblyHelper . ParseHandlerInfo ( pipelineBehaviorType , options . PipelineBehaviorTypes , handlerCollection . AllPipelineBehaviorHandlers ) ;
7657
7758 if ( options . RequestHandlerTypes != null && options . RegisterRequestHandlers )
78- MediatorAssemblyHelper . ParseHandlerInfo ( requestHandlerType , options . RequestHandlerTypes , allHandlers ) ;
59+ MediatorAssemblyHelper . ParseHandlerInfo ( requestHandlerType , options . RequestHandlerTypes , handlerCollection . AllHandlers ) ;
7960
8061 if ( options . StreamRequestHandlerTypes != null && options . RegisterStreamRequestHandlers )
81- MediatorAssemblyHelper . ParseHandlerInfo ( streamRequestHandlerType , options . StreamRequestHandlerTypes , allStreamHandlers ) ;
62+ MediatorAssemblyHelper . ParseHandlerInfo ( streamRequestHandlerType , options . StreamRequestHandlerTypes , handlerCollection . AllStreamHandlers ) ;
8263
8364 if ( options . StreamPipelineBehaviorTypes != null && options . RegisterStreamPipelineBehaviors )
84- MediatorAssemblyHelper . ParseHandlerInfo ( streamPipelineBehaviorType , options . StreamPipelineBehaviorTypes , allStreamPipelineBehaviorHandlers ) ;
65+ MediatorAssemblyHelper . ParseHandlerInfo ( streamPipelineBehaviorType , options . StreamPipelineBehaviorTypes , handlerCollection . AllStreamPipelineBehaviorHandlers ) ;
8566
8667 if ( options . NotificationHandlerTypes != null && options . RegisterNotificationHandlers )
87- MediatorAssemblyHelper . ParseNotificationHandlers ( options . NotificationHandlerTypes , allNotificationHandlers ) ;
68+ MediatorAssemblyHelper . ParseNotificationHandlers ( options . NotificationHandlerTypes , handlerCollection . AllNotificationHandlers ) ;
8869
89- for ( int i = 0 ; i < allHandlers . Count ; i ++ )
70+ for ( int i = 0 ; i < handlerCollection . AllHandlers . Count ; i ++ )
9071 {
91- var handlerInfo = allHandlers [ i ] ;
72+ var handlerInfo = handlerCollection . AllHandlers [ i ] ;
9273 serviceContext . TryRegister ( handlerInfo . CreateRequestHandlerInterfaceType ( ) , handlerInfo . HandlerType , serviceLifetime ) ;
9374 }
9475
95- for ( int i = 0 ; i < allStreamHandlers . Count ; i ++ )
76+ for ( int i = 0 ; i < handlerCollection . AllStreamHandlers . Count ; i ++ )
9677 {
97- var handlerInfo = allStreamHandlers [ i ] ;
78+ var handlerInfo = handlerCollection . AllStreamHandlers [ i ] ;
9879 serviceContext . TryRegister ( handlerInfo . CreateStreamRequestHandlerInterfaceType ( ) , handlerInfo . HandlerType , serviceLifetime ) ;
9980 }
10081
101- if ( options . RegisterPipelineBehaviors && allPipelineBehaviorHandlers . Count > 0 )
82+ if ( options . RegisterPipelineBehaviors && handlerCollection . AllPipelineBehaviorHandlers . Count > 0 )
10283 AddPipelineBehaviors < IGlobalPipelineRegistry , GlobalPipelineRegistry , PipelineBehaviorHandlerInfo > (
10384 serviceContext ,
10485 serviceLifetime ,
105- allPipelineBehaviorHandlers ,
86+ handlerCollection . AllPipelineBehaviorHandlers ,
10687 append ) ;
10788
108- if ( options . RegisterStreamPipelineBehaviors && allStreamPipelineBehaviorHandlers . Count > 0 )
89+ if ( options . RegisterStreamPipelineBehaviors && handlerCollection . AllStreamPipelineBehaviorHandlers . Count > 0 )
10990 AddPipelineBehaviors < IGlobalStreamPipelineRegistry , GlobalStreamPipelineRegistry , StreamPipelineBehaviorHandlerInfo > (
11091 serviceContext ,
11192 serviceLifetime ,
112- allStreamPipelineBehaviorHandlers ,
93+ handlerCollection . AllStreamPipelineBehaviorHandlers ,
11394 append ) ;
11495
115- if ( options . RegisterNotificationHandlers && allNotificationHandlers . Count > 0 )
116- AddNotificationHandlers ( serviceContext , serviceLifetime , allNotificationHandlers , append ) ;
96+ if ( options . RegisterNotificationHandlers && handlerCollection . AllNotificationHandlers . Count > 0 )
97+ AddNotificationHandlers ( serviceContext , serviceLifetime , handlerCollection . AllNotificationHandlers , append ) ;
98+ }
99+
100+ /// <summary>
101+ /// Adds Mediator services to the specified service context.
102+ /// </summary>
103+ /// <param name="serviceContext">The service context.</param>
104+ /// <param name="options">The options.</param>
105+ /// <param name="serviceLifetime">The service lifetime.</param>
106+ /// <param name="append">Whether to append to existing registrations or replace them.</param>
107+ /// <param name="customCallback">A custom callback to execute at the start during registration.</param>
108+ [ RequiresUnreferencedCode ( "Assembly scanning requires unreferenced code. Use explicit handler registration for AOT compatibility." ) ]
109+ [ RequiresDynamicCode ( "Creating generic handler types at runtime requires dynamic code. Use explicit handler registration for AOT compatibility." ) ]
110+ public static void AddSnowberryMediator (
111+ IServiceContext serviceContext ,
112+ MediatorOptions options ,
113+ RegistrationServiceLifetime serviceLifetime ,
114+ bool append ,
115+ CustomAddCallbackDelegate ? customCallback = null )
116+ {
117+ AddSnowberryMediatorNoScan ( serviceContext , options , serviceLifetime , append , ( _ , _ , _ , handlerCollection , _ ) =>
118+ {
119+ if ( options . Assemblies != null && options . Assemblies . Count > 0 )
120+ {
121+ for ( int i = 0 ; i < options . Assemblies . Count ; i ++ )
122+ {
123+ var assembly = options . Assemblies [ i ] ;
124+ ScanAssembly ( options , handlerCollection , assembly ) ;
125+ }
126+ }
127+
128+ customCallback ? . Invoke ( serviceContext , options , serviceLifetime , handlerCollection , append ) ;
129+ } ) ;
130+ }
131+
132+ [ RequiresUnreferencedCode ( "Assembly scanning requires unreferenced code. Use explicit handler registration for AOT compatibility." ) ]
133+ public static void ScanAssembly ( MediatorOptions options , HandlerCollection handlerCollection , Assembly assembly )
134+ {
135+ var scanResult = MediatorAssemblyHelper . ScanAssembly ( assembly ) ;
136+
137+ if ( scanResult . RequestHandlerTypes != null )
138+ for ( int j = 0 ; j < scanResult . RequestHandlerTypes . Count ; j ++ )
139+ handlerCollection . AllHandlers . Add ( scanResult . RequestHandlerTypes [ j ] ) ;
140+
141+ if ( scanResult . StreamRequestHandlerTypes != null )
142+ for ( int j = 0 ; j < scanResult . StreamRequestHandlerTypes . Count ; j ++ )
143+ handlerCollection . AllStreamHandlers . Add ( scanResult . StreamRequestHandlerTypes [ j ] ) ;
144+
145+ if ( options . RegisterPipelineBehaviors && options . ScanPipelineBehaviors && scanResult . PipelineBehaviorTypes != null )
146+ for ( int j = 0 ; j < scanResult . PipelineBehaviorTypes . Count ; j ++ )
147+ handlerCollection . AllPipelineBehaviorHandlers . Add ( scanResult . PipelineBehaviorTypes [ j ] ) ;
148+
149+ if ( options . RegisterStreamPipelineBehaviors && options . ScanStreamPipelineBehaviors && scanResult . StreamPipelineBehaviorTypes != null )
150+ for ( int j = 0 ; j < scanResult . StreamPipelineBehaviorTypes . Count ; j ++ )
151+ handlerCollection . AllStreamPipelineBehaviorHandlers . Add ( scanResult . StreamPipelineBehaviorTypes [ j ] ) ;
152+
153+ if ( options . RegisterNotificationHandlers && options . ScanNotificationHandlers && scanResult . NotificationHandlerTypes != null )
154+ for ( int j = 0 ; j < scanResult . NotificationHandlerTypes . Count ; j ++ )
155+ handlerCollection . AllNotificationHandlers . Add ( scanResult . NotificationHandlerTypes [ j ] ) ;
117156 }
118157
119158 private static void AddPipelineBehaviors < TGlobalPipelineInterface , TGlobalPipelineRegistry , THandlerInfo > (
@@ -191,4 +230,13 @@ bool append
191230 serviceContext . TryRegister ( handler . HandlerType , handler . HandlerType , serviceLifetime ) ;
192231 }
193232 }
233+
234+ public class HandlerCollection
235+ {
236+ public readonly List < RequestHandlerInfo > AllHandlers = [ ] ;
237+ public readonly List < StreamRequestHandlerInfo > AllStreamHandlers = [ ] ;
238+ public readonly List < PipelineBehaviorHandlerInfo > AllPipelineBehaviorHandlers = [ ] ;
239+ public readonly List < StreamPipelineBehaviorHandlerInfo > AllStreamPipelineBehaviorHandlers = [ ] ;
240+ public readonly List < NotificationHandlerInfo > AllNotificationHandlers = [ ] ;
241+ }
194242}
0 commit comments