@@ -11,178 +11,169 @@ public static void RegisterHandlers(IServiceCollection services, List<Type> allT
1111 Type requestHandlerType , Type pipelineBehaviorType , Type streamRequestHandlerType ,
1212 Type streamPipelineBehaviorType , bool withPipelines , List < Type > ? pipelineOrder = null )
1313 {
14+ var handlerTypes = new [ ] { requestHandlerType , streamRequestHandlerType } ;
15+ var pipelineTypes = new [ ] { pipelineBehaviorType , streamPipelineBehaviorType } ;
16+
1417 var allHandlers = allTypes
15- . Where ( p =>
18+ . Where ( type =>
1619 {
17- var @interface = p . GetInterfaces ( ) . First ( i => i . IsGenericType ) ;
18- return new [ ] { requestHandlerType , streamRequestHandlerType }
19- . Contains ( @interface . GetGenericTypeDefinition ( ) ) ;
20- } ) . ToList ( ) ;
20+ var genericInterfaces = type . GetInterfaces ( )
21+ . Where ( i => i . IsGenericType )
22+ . Select ( i => i . GetGenericTypeDefinition ( ) )
23+ . ToList ( ) ;
24+
25+ return genericInterfaces . Intersect ( handlerTypes ) . Any ( ) &&
26+ ! genericInterfaces . Intersect ( pipelineTypes ) . Any ( ) ;
27+ } )
28+ . ToList ( ) ;
2129
2230 var allPipelines = allTypes
23- . Where ( p =>
24- {
25- var @interface = p . GetInterfaces ( ) . First ( i => i . IsGenericType ) ;
26- return new [ ] { pipelineBehaviorType , streamPipelineBehaviorType }
27- . Contains ( @interface . GetGenericTypeDefinition ( ) ) ;
28- } ) . ToList ( ) ;
31+ . Where ( type => type . GetInterfaces ( )
32+ . Where ( i => i . IsGenericType )
33+ . Select ( i => i . GetGenericTypeDefinition ( ) )
34+ . Intersect ( pipelineTypes )
35+ . Any ( ) )
36+ . ToList ( ) ;
2937
3038 foreach ( var handler in allHandlers )
3139 {
32- object key = handler . GUID ;
33- var handlerType = requestHandlerType ;
34- var behaviorType = pipelineBehaviorType ;
40+ var handlerInterfaces = handler . GetInterfaces ( )
41+ . Where ( p => p . IsGenericType && handlerTypes . Contains ( p . GetGenericTypeDefinition ( ) ) )
42+ . ToList ( ) ;
3543
36- var isStream = handler . GetInterfaces ( )
37- . Any ( p => p . IsGenericType && p . GetGenericTypeDefinition ( ) == streamRequestHandlerType ) ;
38- if ( isStream )
44+ foreach ( var handlerInterface in handlerInterfaces )
3945 {
40- handlerType = streamRequestHandlerType ;
41- behaviorType = streamPipelineBehaviorType ;
42- }
43-
44- services . AddKeyedScoped ( typeof ( IRequestHandler ) , key , handler ) ;
45-
46- var handlerInterface = handler . GetInterfaces ( )
47- . First ( p => p . IsGenericType && p . GetGenericTypeDefinition ( ) == handlerType ) ;
46+ object key = Guid . NewGuid ( ) ;
47+ var handlerType = requestHandlerType ;
48+ var behaviorType = pipelineBehaviorType ;
4849
49- // find pipelines
50- if ( withPipelines )
51- {
52- var pipelines = allPipelines
53- . Where ( p =>
54- {
55- var interfaces = p . GetInterfaces ( ) ;
56- if ( p . IsGenericType )
57- {
58- // handle generic pipelines
59- return interfaces
60- . FirstOrDefault ( inter =>
61- inter . IsGenericType &&
62- inter . GetGenericTypeDefinition ( ) == behaviorType )
63- ? . GetInterfaces ( ) . First ( ) . GetGenericTypeDefinition ( ) ==
64- handlerInterface . GetGenericTypeDefinition ( ) ;
65- }
50+ var isStream = handlerInterface . GetGenericTypeDefinition ( ) == streamRequestHandlerType ;
51+ if ( isStream )
52+ {
53+ handlerType = streamRequestHandlerType ;
54+ behaviorType = streamPipelineBehaviorType ;
55+ }
6656
67- return interfaces
68- . FirstOrDefault ( inter =>
69- inter . IsGenericType &&
70- inter . GetGenericTypeDefinition ( ) == behaviorType )
71- ? . GetInterfaces ( ) . First ( ) == handlerInterface ;
72- } ) . ToList ( ) ;
57+ services . AddKeyedScoped ( typeof ( IRequestHandler ) , key , handler ) ;
7358
74- // Sort pipelines by the specified order passed via ConfigurationOptions
75- if ( pipelineOrder is { Count : > 0 } )
59+ // find pipelines
60+ if ( withPipelines )
7661 {
77- pipelines = pipelines
78- . OrderBy ( p =>
62+ var pipelines = allPipelines
63+ . Where ( p =>
7964 {
80- var idx = pipelineOrder . IndexOf ( p ) ;
81- return idx == - 1 ? int . MaxValue : idx ;
82- } )
83- . ToList ( ) ;
84- pipelines . Reverse ( ) ;
85- }
65+ var interfaces = p . GetInterfaces ( ) ;
66+ if ( p . IsGenericType )
67+ {
68+ // handle generic pipelines
69+ return interfaces
70+ . FirstOrDefault ( inter =>
71+ inter . IsGenericType &&
72+ inter . GetGenericTypeDefinition ( ) == behaviorType )
73+ ? . GetInterfaces ( ) . First ( ) . GetGenericTypeDefinition ( ) ==
74+ handlerInterface . GetGenericTypeDefinition ( ) ;
75+ }
8676
87- foreach ( var pipeline in pipelines )
88- {
89- if ( pipeline . IsGenericType )
77+ return interfaces
78+ . FirstOrDefault ( inter =>
79+ inter . IsGenericType &&
80+ inter . GetGenericTypeDefinition ( ) == behaviorType )
81+ ? . GetInterfaces ( ) . First ( ) == handlerInterface ;
82+ } ) . ToList ( ) ;
83+
84+ // Sort pipelines by the specified order passed via ConfigurationOptions
85+ if ( pipelineOrder is { Count : > 0 } )
9086 {
91- var genericHandlerResponseType = pipeline . GetInterfaces ( ) . First ( inter =>
92- inter . IsGenericType &&
93- inter . GetGenericTypeDefinition ( ) == behaviorType ) . GenericTypeArguments [ 1 ] ;
87+ pipelines = pipelines
88+ . OrderBy ( p =>
89+ {
90+ var idx = pipelineOrder . IndexOf ( p ) ;
91+ return idx == - 1 ? int . MaxValue : idx ;
92+ } )
93+ . ToList ( ) ;
94+ pipelines . Reverse ( ) ;
95+ }
9496
95- var genericHandlerResponseIsAwaitable = IsAwaitable ( genericHandlerResponseType ) ;
96- var handlerResponseTypeIsAwaitable = IsAwaitable ( handlerInterface . GenericTypeArguments [ 1 ] ) ;
97- if ( genericHandlerResponseIsAwaitable ^ handlerResponseTypeIsAwaitable )
97+ foreach ( var pipeline in pipelines )
98+ {
99+ if ( pipeline . IsGenericType )
98100 {
99- continue ;
100- }
101+ var genericHandlerResponseType = pipeline . GetInterfaces ( ) . First ( inter =>
102+ inter . IsGenericType &&
103+ inter . GetGenericTypeDefinition ( ) == behaviorType ) . GenericTypeArguments [ 1 ] ;
101104
102- var responseTypeArg = handlerInterface . GenericTypeArguments [ 1 ] ;
103- if ( genericHandlerResponseIsAwaitable && handlerResponseTypeIsAwaitable )
104- {
105- var areGenericTypeArgumentsInHandlerInterfaceMismatched =
106- genericHandlerResponseType . IsGenericType &&
107- handlerInterface . GenericTypeArguments [ 1 ] . IsGenericType &&
108- genericHandlerResponseType . GetGenericTypeDefinition ( ) !=
109- handlerInterface . GenericTypeArguments [ 1 ] . GetGenericTypeDefinition ( ) ;
110-
111- if ( areGenericTypeArgumentsInHandlerInterfaceMismatched ||
112- genericHandlerResponseType . IsGenericType ^
113- handlerInterface . GenericTypeArguments [ 1 ] . IsGenericType )
105+ var genericHandlerResponseIsAwaitable = IsAwaitable ( genericHandlerResponseType ) ;
106+ var handlerResponseTypeIsAwaitable = IsAwaitable ( handlerInterface . GenericTypeArguments [ 1 ] ) ;
107+ if ( genericHandlerResponseIsAwaitable ^ handlerResponseTypeIsAwaitable )
114108 {
115109 continue ;
116110 }
117111
118- // register async generic pipelines
119- if ( responseTypeArg . GenericTypeArguments . Any ( ) )
112+ var responseTypeArg = handlerInterface . GenericTypeArguments [ 1 ] ;
113+ if ( genericHandlerResponseIsAwaitable && handlerResponseTypeIsAwaitable )
120114 {
121- responseTypeArg = responseTypeArg . GenericTypeArguments [ 0 ] ;
115+ var areGenericTypeArgumentsInHandlerInterfaceMismatched =
116+ genericHandlerResponseType . IsGenericType &&
117+ handlerInterface . GenericTypeArguments [ 1 ] . IsGenericType &&
118+ genericHandlerResponseType . GetGenericTypeDefinition ( ) !=
119+ handlerInterface . GenericTypeArguments [ 1 ] . GetGenericTypeDefinition ( ) ;
120+
121+ if ( areGenericTypeArgumentsInHandlerInterfaceMismatched ||
122+ genericHandlerResponseType . IsGenericType ^
123+ handlerInterface . GenericTypeArguments [ 1 ] . IsGenericType )
124+ {
125+ continue ;
126+ }
127+
128+ // register async generic pipelines
129+ if ( responseTypeArg . GenericTypeArguments . Any ( ) )
130+ {
131+ responseTypeArg = responseTypeArg . GenericTypeArguments [ 0 ] ;
132+ }
122133 }
123- }
124134
125- var closedGenericType = pipeline . MakeGenericType ( handlerInterface . GenericTypeArguments [ 0 ] ,
126- responseTypeArg ) ;
127- services . AddKeyedScoped ( typeof ( IRequestHandler ) , key , closedGenericType ) ;
128- }
129- else
130- {
131- services . AddKeyedScoped ( typeof ( IRequestHandler ) , key , pipeline ) ;
135+ var closedGenericType = pipeline . MakeGenericType ( handlerInterface . GenericTypeArguments [ 0 ] ,
136+ responseTypeArg ) ;
137+ services . AddKeyedScoped ( typeof ( IRequestHandler ) , key , closedGenericType ) ;
138+ }
139+ else
140+ {
141+ services . AddKeyedScoped ( typeof ( IRequestHandler ) , key , pipeline ) ;
142+ }
132143 }
133144 }
134- }
135-
136- services . AddScoped ( handlerInterface , sp =>
137- {
138- var pipelinesWithHandler = Unsafe
139- . As < IRequestHandler [ ] > ( sp . GetKeyedServices < IRequestHandler > ( key ) ) ;
140145
141- IRequestHandler lastPipeline = pipelinesWithHandler [ 0 ] ;
142- for ( int i = 1 ; i < pipelinesWithHandler . Length ; i ++ )
146+ services . AddScoped ( handlerInterface , sp =>
143147 {
144- var pipeline = pipelinesWithHandler [ i ] ;
145- pipeline . SetNext ( lastPipeline ) ;
146- lastPipeline = pipeline ;
147- }
148+ var pipelinesWithHandler = Unsafe
149+ . As < IRequestHandler [ ] > ( sp . GetKeyedServices < IRequestHandler > ( key ) ) ;
148150
149- return lastPipeline ;
150- } ) ;
151+ IRequestHandler lastPipeline = pipelinesWithHandler [ 0 ] ;
152+ for ( int i = 1 ; i < pipelinesWithHandler . Length ; i ++ )
153+ {
154+ var pipeline = pipelinesWithHandler [ i ] ;
155+ pipeline . SetNext ( lastPipeline ) ;
156+ lastPipeline = pipeline ;
157+ }
158+
159+ return lastPipeline ;
160+ } ) ;
161+ }
151162 }
152163 }
153164
154165 public static void RegisterNotification ( IServiceCollection services , List < Type > allTypes ,
155166 Type syncNotificationHandlerType )
156167 {
157168 var allNotifications = allTypes
158- . Where ( p =>
159- {
160- return p . GetInterfaces ( )
161- . Where ( i => i . IsGenericType )
162- . Select ( i => i . GetGenericTypeDefinition ( ) )
163- . Any ( i => new [ ]
164- {
165- syncNotificationHandlerType
166- } . Contains ( i ) ) ;
167- } )
168- . GroupBy ( p =>
169- {
170- var @interface = p . GetInterfaces ( )
171- . Where ( i => i . IsGenericType )
172- . First ( i => new [ ]
173- {
174- syncNotificationHandlerType
175- } . Contains ( i . GetGenericTypeDefinition ( ) ) ) ;
176- return @interface . GenericTypeArguments . First ( ) ;
177- } )
169+ . SelectMany ( handlerType => handlerType . GetInterfaces ( )
170+ . Where ( i => i . IsGenericType && syncNotificationHandlerType == i . GetGenericTypeDefinition ( ) )
171+ . Select ( i => new { HandlerType = handlerType , Interface = i } ) )
178172 . ToList ( ) ;
179173
180174 foreach ( var notification in allNotifications )
181175 {
182- foreach ( var types in notification . ToList ( ) )
183- {
184- services . AddScoped ( typeof ( INotificationHandler < > ) . MakeGenericType ( notification . Key ) , types ) ;
185- }
176+ services . AddScoped ( notification . Interface , notification . HandlerType ) ;
186177 }
187178 }
188179
0 commit comments