11using System . Diagnostics . CodeAnalysis ;
2+ using System . Reflection ;
23using Snowberry . Mediator . Abstractions ;
34using Snowberry . Mediator . Abstractions . Handler ;
45using Snowberry . Mediator . Abstractions . Pipeline ;
@@ -15,108 +16,143 @@ namespace Snowberry.Mediator.DependencyInjection.Shared;
1516/// </summary>
1617public static class DependencyInjectionHelper
1718{
19+ public delegate void CustomAddCallbackDelegate (
20+ IServiceContext serviceContext ,
21+ MediatorOptions options ,
22+ RegistrationServiceLifetime serviceLifetime ,
23+ HandlerCollection handlerCollection ,
24+ bool append ) ;
25+
1826 /// <summary>
1927 /// Adds Mediator services to the specified service context.
2028 /// </summary>
29+ /// <remarks>This variant ignores the <see cref="MediatorOptions.Assemblies"/> option to be more compatible with AOT scenarios.</remarks>
2130 /// <param name="serviceContext">The service context.</param>
2231 /// <param name="options">The options.</param>
2332 /// <param name="serviceLifetime">The service lifetime.</param>
2433 /// <param name="append">Whether to append to existing registrations or replace them.</param>
25- [ RequiresUnreferencedCode ( "Assembly scanning requires unreferenced code. Use explicit handler registration for AOT compatibility." ) ]
34+ /// <param name="customCallback">A custom callback to execute at the start during registration.</param>
2635 [ RequiresDynamicCode ( "Creating generic handler types at runtime requires dynamic code. Use explicit handler registration for AOT compatibility." ) ]
27- public static void AddSnowberryMediator (
36+ public static void AddSnowberryMediatorNoScan (
2837 IServiceContext serviceContext ,
2938 MediatorOptions options ,
3039 RegistrationServiceLifetime serviceLifetime ,
31- bool append )
40+ bool append ,
41+ CustomAddCallbackDelegate ? customCallback )
3242 {
3343 if ( ! append || ! serviceContext . IsServiceRegistered < IMediator > ( ) )
3444 serviceContext . TryRegister ( typeof ( IMediator ) , typeof ( Mediator ) , serviceLifetime ) ;
3545
36- var allHandlers = new List < RequestHandlerInfo > ( ) ;
37- var allStreamHandlers = new List < StreamRequestHandlerInfo > ( ) ;
38- var allPipelineBehaviorHandlers = new List < PipelineBehaviorHandlerInfo > ( ) ;
39- var allStreamPipelineBehaviorHandlers = new List < StreamPipelineBehaviorHandlerInfo > ( ) ;
40- var allNotificationHandlers = new List < NotificationHandlerInfo > ( ) ;
41-
42- if ( options . Assemblies != null && options . Assemblies . Count > 0 )
43- {
44- for ( int i = 0 ; i < options . Assemblies . Count ; i ++ )
45- {
46- var assembly = options . Assemblies [ i ] ;
47-
48- var scanResult = MediatorAssemblyHelper . ScanAssembly ( assembly ) ;
49-
50- if ( scanResult . RequestHandlerTypes != null )
51- for ( int j = 0 ; j < scanResult . RequestHandlerTypes . Count ; j ++ )
52- allHandlers . Add ( scanResult . RequestHandlerTypes [ j ] ) ;
53-
54- if ( scanResult . StreamRequestHandlerTypes != null )
55- for ( int j = 0 ; j < scanResult . StreamRequestHandlerTypes . Count ; j ++ )
56- allStreamHandlers . Add ( scanResult . StreamRequestHandlerTypes [ j ] ) ;
46+ var handlerCollection = new HandlerCollection ( ) ;
5747
58- if ( options . RegisterPipelineBehaviors && options . ScanPipelineBehaviors && scanResult . PipelineBehaviorTypes != null )
59- for ( int j = 0 ; j < scanResult . PipelineBehaviorTypes . Count ; j ++ )
60- allPipelineBehaviorHandlers . Add ( scanResult . PipelineBehaviorTypes [ j ] ) ;
61-
62- if ( options . RegisterStreamPipelineBehaviors && options . ScanStreamPipelineBehaviors && scanResult . StreamPipelineBehaviorTypes != null )
63- for ( int j = 0 ; j < scanResult . StreamPipelineBehaviorTypes . Count ; j ++ )
64- allStreamPipelineBehaviorHandlers . Add ( scanResult . StreamPipelineBehaviorTypes [ j ] ) ;
65-
66- if ( options . RegisterNotificationHandlers && options . ScanNotificationHandlers && scanResult . NotificationHandlerTypes != null )
67- for ( int j = 0 ; j < scanResult . NotificationHandlerTypes . Count ; j ++ )
68- allNotificationHandlers . Add ( scanResult . NotificationHandlerTypes [ j ] ) ;
69- }
70- }
48+ customCallback ? . Invoke ( serviceContext , options , serviceLifetime , handlerCollection , append ) ;
7149
7250 var pipelineBehaviorType = typeof ( IPipelineBehavior < , > ) ;
7351 var streamPipelineBehaviorType = typeof ( IStreamPipelineBehavior < , > ) ;
7452 var requestHandlerType = typeof ( IRequestHandler < , > ) ;
7553 var streamRequestHandlerType = typeof ( IStreamRequestHandler < , > ) ;
7654
7755 if ( options . PipelineBehaviorTypes != null && options . RegisterPipelineBehaviors )
78- MediatorAssemblyHelper . ParseHandlerInfo ( pipelineBehaviorType , options . PipelineBehaviorTypes , allPipelineBehaviorHandlers ) ;
56+ MediatorAssemblyHelper . ParseHandlerInfo ( pipelineBehaviorType , options . PipelineBehaviorTypes , handlerCollection . AllPipelineBehaviorHandlers ) ;
7957
8058 if ( options . RequestHandlerTypes != null && options . RegisterRequestHandlers )
81- MediatorAssemblyHelper . ParseHandlerInfo ( requestHandlerType , options . RequestHandlerTypes , allHandlers ) ;
59+ MediatorAssemblyHelper . ParseHandlerInfo ( requestHandlerType , options . RequestHandlerTypes , handlerCollection . AllHandlers ) ;
8260
8361 if ( options . StreamRequestHandlerTypes != null && options . RegisterStreamRequestHandlers )
84- MediatorAssemblyHelper . ParseHandlerInfo ( streamRequestHandlerType , options . StreamRequestHandlerTypes , allStreamHandlers ) ;
62+ MediatorAssemblyHelper . ParseHandlerInfo ( streamRequestHandlerType , options . StreamRequestHandlerTypes , handlerCollection . AllStreamHandlers ) ;
8563
8664 if ( options . StreamPipelineBehaviorTypes != null && options . RegisterStreamPipelineBehaviors )
87- MediatorAssemblyHelper . ParseHandlerInfo ( streamPipelineBehaviorType , options . StreamPipelineBehaviorTypes , allStreamPipelineBehaviorHandlers ) ;
65+ MediatorAssemblyHelper . ParseHandlerInfo ( streamPipelineBehaviorType , options . StreamPipelineBehaviorTypes , handlerCollection . AllStreamPipelineBehaviorHandlers ) ;
8866
8967 if ( options . NotificationHandlerTypes != null && options . RegisterNotificationHandlers )
90- MediatorAssemblyHelper . ParseNotificationHandlers ( options . NotificationHandlerTypes , allNotificationHandlers ) ;
68+ MediatorAssemblyHelper . ParseNotificationHandlers ( options . NotificationHandlerTypes , handlerCollection . AllNotificationHandlers ) ;
9169
92- for ( int i = 0 ; i < allHandlers . Count ; i ++ )
70+ for ( int i = 0 ; i < handlerCollection . AllHandlers . Count ; i ++ )
9371 {
94- var handlerInfo = allHandlers [ i ] ;
72+ var handlerInfo = handlerCollection . AllHandlers [ i ] ;
9573 serviceContext . TryRegister ( handlerInfo . CreateRequestHandlerInterfaceType ( ) , handlerInfo . HandlerType , serviceLifetime ) ;
9674 }
9775
98- for ( int i = 0 ; i < allStreamHandlers . Count ; i ++ )
76+ for ( int i = 0 ; i < handlerCollection . AllStreamHandlers . Count ; i ++ )
9977 {
100- var handlerInfo = allStreamHandlers [ i ] ;
78+ var handlerInfo = handlerCollection . AllStreamHandlers [ i ] ;
10179 serviceContext . TryRegister ( handlerInfo . CreateStreamRequestHandlerInterfaceType ( ) , handlerInfo . HandlerType , serviceLifetime ) ;
10280 }
10381
104- if ( options . RegisterPipelineBehaviors && allPipelineBehaviorHandlers . Count > 0 )
82+ if ( options . RegisterPipelineBehaviors && handlerCollection . AllPipelineBehaviorHandlers . Count > 0 )
10583 AddPipelineBehaviors < IGlobalPipelineRegistry , GlobalPipelineRegistry , PipelineBehaviorHandlerInfo > (
10684 serviceContext ,
10785 serviceLifetime ,
108- allPipelineBehaviorHandlers ,
86+ handlerCollection . AllPipelineBehaviorHandlers ,
10987 append ) ;
11088
111- if ( options . RegisterStreamPipelineBehaviors && allStreamPipelineBehaviorHandlers . Count > 0 )
89+ if ( options . RegisterStreamPipelineBehaviors && handlerCollection . AllStreamPipelineBehaviorHandlers . Count > 0 )
11290 AddPipelineBehaviors < IGlobalStreamPipelineRegistry , GlobalStreamPipelineRegistry , StreamPipelineBehaviorHandlerInfo > (
11391 serviceContext ,
11492 serviceLifetime ,
115- allStreamPipelineBehaviorHandlers ,
93+ handlerCollection . AllStreamPipelineBehaviorHandlers ,
11694 append ) ;
11795
118- if ( options . RegisterNotificationHandlers && allNotificationHandlers . Count > 0 )
119- 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 ] ) ;
120156 }
121157
122158 private static void AddPipelineBehaviors < TGlobalPipelineInterface , TGlobalPipelineRegistry , THandlerInfo > (
@@ -194,4 +230,13 @@ bool append
194230 serviceContext . TryRegister ( handler . HandlerType , handler . HandlerType , serviceLifetime ) ;
195231 }
196232 }
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+ }
197242}
0 commit comments