55
66namespace CodeChavez . M3diator ;
77
8+ /// <summary>
9+ /// M3diator implementation allow access to Handle and Notification handlers
10+ /// </summary>
811public class M3diator : IM3diator
912{
1013 private readonly IServiceProvider _serviceProvider ;
1114 private static readonly ConcurrentDictionary < Type , Func < IServiceProvider , object , CancellationToken , ValueTask > > _voidHandlers = new ( ) ;
1215 private static readonly ConcurrentDictionary < Type , Func < IServiceProvider , object , CancellationToken , ValueTask < object > > > _responseHandlers = new ( ) ;
1316 private static readonly ConcurrentDictionary < Type , Func < IServiceProvider , object , CancellationToken , Task > > _notificationHandlers = new ( ) ;
1417
18+ /// <summary>
19+ /// Initializes a new instance of the <see cref="M3diator"/> class
20+ /// </summary>
21+ /// <param name="sp">Service Provider</param>
1522 public M3diator ( IServiceProvider sp )
1623 {
1724 _serviceProvider = sp ;
1825 }
1926
20- // Handle commands/queries with responses
27+ /// <summary>
28+ /// Handles requests with Response
29+ /// </summary>
30+ /// <typeparam name="TResponse"></typeparam>
31+ /// <param name="request"></param>
32+ /// <param name="ct"></param>
33+ /// <returns></returns>
2134 public async Task < TResponse > Handle < TResponse > ( IRequest < TResponse > request , CancellationToken ct = default )
2235 {
2336 var handlerFunc = _responseHandlers . GetOrAdd ( request . GetType ( ) , static reqType =>
@@ -32,16 +45,23 @@ public async Task<TResponse> Handle<TResponse>(IRequest<TResponse> request, Canc
3245 var getHandlerCall = Expression . Call (
3346 typeof ( ServiceProviderServiceExtensions ) ,
3447 nameof ( ServiceProviderServiceExtensions . GetRequiredService ) ,
35- [ handlerType ] ,
48+ new [ ] { handlerType } ,
3649 spParam
3750 ) ;
3851
3952 var castRequest = Expression . Convert ( reqParam , reqType ) ;
4053 var callHandle = Expression . Call ( getHandlerCall , handleMethod , castRequest , ctParam ) ;
4154
42- var castResult = Expression . Convert ( callHandle , typeof ( object ) ) ;
55+ // Convert Task<TResponse> to ValueTask<object>
56+ var wrapCall = Expression . Call (
57+ typeof ( M3diator ) ,
58+ nameof ( WrapTaskAsValueTask ) ,
59+ new [ ] { typeof ( TResponse ) } ,
60+ callHandle
61+ ) ;
62+
4363 var lambda = Expression . Lambda < Func < IServiceProvider , object , CancellationToken , ValueTask < object > > > (
44- Expression . Convert ( castResult , typeof ( ValueTask < object > ) ) ,
64+ wrapCall ,
4565 spParam , reqParam , ctParam
4666 ) ;
4767
@@ -52,7 +72,19 @@ public async Task<TResponse> Handle<TResponse>(IRequest<TResponse> request, Canc
5272 return ( TResponse ) result ;
5373 }
5474
55- // Handle commands with no response
75+ private static async ValueTask < object > WrapTaskAsValueTask < T > ( Task < T > task )
76+ {
77+ var result = await task . ConfigureAwait ( false ) ;
78+ return result ! ;
79+ }
80+
81+ /// <summary>
82+ /// Handles requests with no response
83+ /// </summary>
84+ /// <typeparam name="TRequest"></typeparam>
85+ /// <param name="request"></param>
86+ /// <param name="ct"></param>
87+ /// <returns></returns>
5688 public async Task Handle < TRequest > ( TRequest request , CancellationToken ct = default ) where TRequest : IRequest
5789 {
5890 var handlerFunc = _voidHandlers . GetOrAdd ( request . GetType ( ) , static reqType =>
@@ -67,15 +99,23 @@ public async Task Handle<TRequest>(TRequest request, CancellationToken ct = defa
6799 var getHandlerCall = Expression . Call (
68100 typeof ( ServiceProviderServiceExtensions ) ,
69101 nameof ( ServiceProviderServiceExtensions . GetRequiredService ) ,
70- [ handlerType ] ,
102+ new [ ] { handlerType } ,
71103 spParam
72104 ) ;
73105
74106 var castRequest = Expression . Convert ( reqParam , reqType ) ;
75107 var callHandle = Expression . Call ( getHandlerCall , handleMethod , castRequest , ctParam ) ;
76108
109+ // Convert Task to ValueTask
110+ var wrapCall = Expression . Call (
111+ typeof ( M3diator ) ,
112+ nameof ( WrapTaskAsValueTaskVoid ) ,
113+ Type . EmptyTypes ,
114+ callHandle
115+ ) ;
116+
77117 var lambda = Expression . Lambda < Func < IServiceProvider , object , CancellationToken , ValueTask > > (
78- Expression . Convert ( callHandle , typeof ( ValueTask ) ) ,
118+ wrapCall ,
79119 spParam , reqParam , ctParam
80120 ) ;
81121
@@ -84,7 +124,19 @@ public async Task Handle<TRequest>(TRequest request, CancellationToken ct = defa
84124
85125 await handlerFunc ( _serviceProvider , request ! , ct ) ;
86126 }
87-
127+
128+ private static async ValueTask WrapTaskAsValueTaskVoid ( Task task )
129+ {
130+ await task . ConfigureAwait ( false ) ;
131+ }
132+
133+ /// <summary>
134+ /// Publishes INotification
135+ /// </summary>
136+ /// <typeparam name="TNotification"></typeparam>
137+ /// <param name="notification"></param>
138+ /// <param name="ct"></param>
139+ /// <returns></returns>
88140 public async Task Publish < TNotification > ( TNotification notification , CancellationToken ct = default )
89141 where TNotification : INotification
90142 {
@@ -99,4 +151,5 @@ public async Task Publish<TNotification>(TNotification notification, Cancellatio
99151
100152 await Task . WhenAll ( tasks ) ;
101153 }
154+
102155}
0 commit comments