From b7b9d28398db68d402a728c8b750c9763eddb636 Mon Sep 17 00:00:00 2001 From: pauldin91 Date: Sun, 22 Oct 2023 09:47:37 +0300 Subject: [PATCH 1/9] remove activator usage from Send methods, and use new and compiled expressions for constructing RequestHandlerWrapperImpl objects --- src/MediatR/Mediator.cs | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/MediatR/Mediator.cs b/src/MediatR/Mediator.cs index 4d65de18..644dde98 100644 --- a/src/MediatR/Mediator.cs +++ b/src/MediatR/Mediator.cs @@ -6,6 +6,7 @@ namespace MediatR; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; using Wrappers; @@ -25,7 +26,7 @@ public class Mediator : IMediator /// Initializes a new instance of the class. /// /// Service provider. Can be a scoped or root provider - public Mediator(IServiceProvider serviceProvider) + public Mediator(IServiceProvider serviceProvider) : this(serviceProvider, new ForeachAwaitPublisher()) { } /// @@ -46,11 +47,12 @@ public Task Send(IRequest request, Cancellation throw new ArgumentNullException(nameof(request)); } - var handler = (RequestHandlerWrapper)_requestHandlers.GetOrAdd(request.GetType(), static requestType => + var handler = (RequestHandlerWrapper) _requestHandlers.GetOrAdd(request.GetType(), static requestType => { var wrapperType = typeof(RequestHandlerWrapperImpl<,>).MakeGenericType(requestType, typeof(TResponse)); - var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper type for {requestType}"); - return (RequestHandlerBase)wrapper; + var ctor = wrapperType.GetConstructors().First(); + var expression = Expression.Lambda>>(Expression.New(ctor)).Compile() ?? throw new InvalidOperationException($"Could not create wrapper type for {requestType}"); + return expression(); }); return handler.Handle(request, _serviceProvider, cancellationToken); @@ -64,11 +66,16 @@ public Task Send(TRequest request, CancellationToken cancellationToken throw new ArgumentNullException(nameof(request)); } - var handler = (RequestHandlerWrapper)_requestHandlers.GetOrAdd(request.GetType(), static requestType => + var handler = (RequestHandlerWrapper) _requestHandlers.GetOrAdd(request.GetType(), static requestType => { - var wrapperType = typeof(RequestHandlerWrapperImpl<>).MakeGenericType(requestType); - var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper type for {requestType}"); - return (RequestHandlerBase)wrapper; + try + { + return new RequestHandlerWrapperImpl(); + } + catch (Exception) + { + throw new InvalidOperationException($"Could not create wrapper type for {requestType}"); + } }); return handler.Handle(request, _serviceProvider, cancellationToken); @@ -103,7 +110,7 @@ public Task Send(TRequest request, CancellationToken cancellationToken } var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}"); - return (RequestHandlerBase)wrapper; + return (RequestHandlerBase) wrapper; }); // call via dynamic dispatch to avoid calling through reflection for performance reasons @@ -136,7 +143,7 @@ public Task Publish(object notification, CancellationToken cancellationToken = d /// The notification being published /// The cancellation token /// A task representing invoking all handlers - protected virtual Task PublishCore(IEnumerable handlerExecutors, INotification notification, CancellationToken cancellationToken) + protected virtual Task PublishCore(IEnumerable handlerExecutors, INotification notification, CancellationToken cancellationToken) => _publisher.Publish(handlerExecutors, notification, cancellationToken); private Task PublishNotification(INotification notification, CancellationToken cancellationToken = default) @@ -145,13 +152,12 @@ private Task PublishNotification(INotification notification, CancellationToken c { var wrapperType = typeof(NotificationHandlerWrapperImpl<>).MakeGenericType(notificationType); var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {notificationType}"); - return (NotificationHandlerWrapper)wrapper; + return (NotificationHandlerWrapper) wrapper; }); return handler.Handle(notification, _serviceProvider, PublishCore, cancellationToken); } - public IAsyncEnumerable CreateStream(IStreamRequest request, CancellationToken cancellationToken = default) { if (request == null) @@ -159,11 +165,11 @@ public IAsyncEnumerable CreateStream(IStreamRequest)_streamRequestHandlers.GetOrAdd(request.GetType(), static requestType => + var streamHandler = (StreamRequestHandlerWrapper) _streamRequestHandlers.GetOrAdd(request.GetType(), static requestType => { var wrapperType = typeof(StreamRequestHandlerWrapperImpl<,>).MakeGenericType(requestType, typeof(TResponse)); var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}"); - return (StreamRequestHandlerBase)wrapper; + return (StreamRequestHandlerBase) wrapper; }); var items = streamHandler.Handle(request, _serviceProvider, cancellationToken); @@ -171,7 +177,6 @@ public IAsyncEnumerable CreateStream(IStreamRequest CreateStream(object request, CancellationToken cancellationToken = default) { if (request == null) @@ -190,11 +195,11 @@ public IAsyncEnumerable CreateStream(IStreamRequest).MakeGenericType(requestType, responseType); var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}"); - return (StreamRequestHandlerBase)wrapper; + return (StreamRequestHandlerBase) wrapper; }); var items = handler.Handle(request, _serviceProvider, cancellationToken); return items; } -} +} \ No newline at end of file From 73adb45780f60b2242e70f70dc6bc4245ddae44f Mon Sep 17 00:00:00 2001 From: pauldin91 Date: Sun, 22 Oct 2023 10:00:12 +0300 Subject: [PATCH 2/9] remove try catch --- src/MediatR/Mediator.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/MediatR/Mediator.cs b/src/MediatR/Mediator.cs index 644dde98..6100b641 100644 --- a/src/MediatR/Mediator.cs +++ b/src/MediatR/Mediator.cs @@ -68,14 +68,7 @@ public Task Send(TRequest request, CancellationToken cancellationToken var handler = (RequestHandlerWrapper) _requestHandlers.GetOrAdd(request.GetType(), static requestType => { - try - { - return new RequestHandlerWrapperImpl(); - } - catch (Exception) - { - throw new InvalidOperationException($"Could not create wrapper type for {requestType}"); - } + return new RequestHandlerWrapperImpl() ?? throw new InvalidOperationException($"Could not create wrapper type for {requestType}"); }); return handler.Handle(request, _serviceProvider, cancellationToken); From 183c6ce327ca4e32ab7e72d54f0f08aade471524 Mon Sep 17 00:00:00 2001 From: pauldin91 Date: Thu, 2 Nov 2023 10:56:53 +0200 Subject: [PATCH 3/9] Apply construction with lambda expressions in PublishNotification and CreateStream also --- src/MediatR/Mediator.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/MediatR/Mediator.cs b/src/MediatR/Mediator.cs index 6100b641..bc423743 100644 --- a/src/MediatR/Mediator.cs +++ b/src/MediatR/Mediator.cs @@ -143,9 +143,9 @@ private Task PublishNotification(INotification notification, CancellationToken c { var handler = _notificationHandlers.GetOrAdd(notification.GetType(), static notificationType => { - var wrapperType = typeof(NotificationHandlerWrapperImpl<>).MakeGenericType(notificationType); - var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {notificationType}"); - return (NotificationHandlerWrapper) wrapper; + var wrapperType = typeof(NotificationHandlerWrapperImpl<>).MakeGenericType(notificationType); var ctor = wrapperType.GetConstructors().First(); + var wrapper = Expression.Lambda>(Expression.New(ctor)).Compile() ?? throw new InvalidOperationException($"Could not create wrapper for type {notificationType}"); + return wrapper(); }); return handler.Handle(notification, _serviceProvider, PublishCore, cancellationToken); @@ -161,8 +161,9 @@ public IAsyncEnumerable CreateStream(IStreamRequest) _streamRequestHandlers.GetOrAdd(request.GetType(), static requestType => { var wrapperType = typeof(StreamRequestHandlerWrapperImpl<,>).MakeGenericType(requestType, typeof(TResponse)); - var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}"); - return (StreamRequestHandlerBase) wrapper; + var ctor = wrapperType.GetConstructors().First(); + var wrapper = Expression.Lambda>>(Expression.New(ctor)).Compile() ?? throw new InvalidOperationException($"Could not create wrapper type for {requestType}"); + return wrapper(); }); var items = streamHandler.Handle(request, _serviceProvider, cancellationToken); From 92791561e44aea4cc6c3d1d5c1e80d519d16e76c Mon Sep 17 00:00:00 2001 From: pauldin91 Date: Thu, 2 Nov 2023 12:27:01 +0200 Subject: [PATCH 4/9] Replace activator completely from methods CreateStream for object request and Send for object request --- src/MediatR/Mediator.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/MediatR/Mediator.cs b/src/MediatR/Mediator.cs index bc423743..62eac47f 100644 --- a/src/MediatR/Mediator.cs +++ b/src/MediatR/Mediator.cs @@ -101,9 +101,9 @@ public Task Send(TRequest request, CancellationToken cancellationToken var responseType = requestInterfaceType.GetGenericArguments()[0]; wrapperType = typeof(RequestHandlerWrapperImpl<,>).MakeGenericType(requestType, responseType); } - - var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}"); - return (RequestHandlerBase) wrapper; + var ctor = wrapperType.GetConstructors().First(); + var wrapper = Expression.Lambda>(Expression.New(ctor)).Compile() ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}"); + return wrapper(); }); // call via dynamic dispatch to avoid calling through reflection for performance reasons @@ -188,8 +188,9 @@ public IAsyncEnumerable CreateStream(IStreamRequest).MakeGenericType(requestType, responseType); - var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}"); - return (StreamRequestHandlerBase) wrapper; + var ctor = wrapperType.GetConstructors().First(); + var wrapper = Expression.Lambda>(Expression.New(ctor)).Compile() ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}"); + return wrapper(); }); var items = handler.Handle(request, _serviceProvider, cancellationToken); From 066cae960fb3b47e4097b16f94bad5f92608440b Mon Sep 17 00:00:00 2001 From: pauldin91 Date: Tue, 9 Jan 2024 19:20:34 +0200 Subject: [PATCH 5/9] Revert "Replace activator completely from methods CreateStream for object request and Send for object request" This reverts commit 92791561e44aea4cc6c3d1d5c1e80d519d16e76c. --- src/MediatR/Mediator.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/MediatR/Mediator.cs b/src/MediatR/Mediator.cs index 62eac47f..bc423743 100644 --- a/src/MediatR/Mediator.cs +++ b/src/MediatR/Mediator.cs @@ -101,9 +101,9 @@ public Task Send(TRequest request, CancellationToken cancellationToken var responseType = requestInterfaceType.GetGenericArguments()[0]; wrapperType = typeof(RequestHandlerWrapperImpl<,>).MakeGenericType(requestType, responseType); } - var ctor = wrapperType.GetConstructors().First(); - var wrapper = Expression.Lambda>(Expression.New(ctor)).Compile() ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}"); - return wrapper(); + + var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}"); + return (RequestHandlerBase) wrapper; }); // call via dynamic dispatch to avoid calling through reflection for performance reasons @@ -188,9 +188,8 @@ public IAsyncEnumerable CreateStream(IStreamRequest).MakeGenericType(requestType, responseType); - var ctor = wrapperType.GetConstructors().First(); - var wrapper = Expression.Lambda>(Expression.New(ctor)).Compile() ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}"); - return wrapper(); + var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}"); + return (StreamRequestHandlerBase) wrapper; }); var items = handler.Handle(request, _serviceProvider, cancellationToken); From a56ca634b0f0d8464b9ca4c4acdd3a14381a79b8 Mon Sep 17 00:00:00 2001 From: pauldin91 Date: Tue, 9 Jan 2024 19:20:56 +0200 Subject: [PATCH 6/9] Revert "remove try catch" This reverts commit 73adb45780f60b2242e70f70dc6bc4245ddae44f. --- src/MediatR/Mediator.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/MediatR/Mediator.cs b/src/MediatR/Mediator.cs index bc423743..0c56f245 100644 --- a/src/MediatR/Mediator.cs +++ b/src/MediatR/Mediator.cs @@ -68,7 +68,14 @@ public Task Send(TRequest request, CancellationToken cancellationToken var handler = (RequestHandlerWrapper) _requestHandlers.GetOrAdd(request.GetType(), static requestType => { - return new RequestHandlerWrapperImpl() ?? throw new InvalidOperationException($"Could not create wrapper type for {requestType}"); + try + { + return new RequestHandlerWrapperImpl(); + } + catch (Exception) + { + throw new InvalidOperationException($"Could not create wrapper type for {requestType}"); + } }); return handler.Handle(request, _serviceProvider, cancellationToken); From 008fe8ea4163f609809db6604b9c247f39d7579d Mon Sep 17 00:00:00 2001 From: pauldin91 Date: Tue, 9 Jan 2024 19:21:05 +0200 Subject: [PATCH 7/9] Revert "Apply construction with lambda expressions in PublishNotification and CreateStream also" This reverts commit 183c6ce327ca4e32ab7e72d54f0f08aade471524. --- src/MediatR/Mediator.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/MediatR/Mediator.cs b/src/MediatR/Mediator.cs index 0c56f245..644dde98 100644 --- a/src/MediatR/Mediator.cs +++ b/src/MediatR/Mediator.cs @@ -150,9 +150,9 @@ private Task PublishNotification(INotification notification, CancellationToken c { var handler = _notificationHandlers.GetOrAdd(notification.GetType(), static notificationType => { - var wrapperType = typeof(NotificationHandlerWrapperImpl<>).MakeGenericType(notificationType); var ctor = wrapperType.GetConstructors().First(); - var wrapper = Expression.Lambda>(Expression.New(ctor)).Compile() ?? throw new InvalidOperationException($"Could not create wrapper for type {notificationType}"); - return wrapper(); + var wrapperType = typeof(NotificationHandlerWrapperImpl<>).MakeGenericType(notificationType); + var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {notificationType}"); + return (NotificationHandlerWrapper) wrapper; }); return handler.Handle(notification, _serviceProvider, PublishCore, cancellationToken); @@ -168,9 +168,8 @@ public IAsyncEnumerable CreateStream(IStreamRequest) _streamRequestHandlers.GetOrAdd(request.GetType(), static requestType => { var wrapperType = typeof(StreamRequestHandlerWrapperImpl<,>).MakeGenericType(requestType, typeof(TResponse)); - var ctor = wrapperType.GetConstructors().First(); - var wrapper = Expression.Lambda>>(Expression.New(ctor)).Compile() ?? throw new InvalidOperationException($"Could not create wrapper type for {requestType}"); - return wrapper(); + var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}"); + return (StreamRequestHandlerBase) wrapper; }); var items = streamHandler.Handle(request, _serviceProvider, cancellationToken); From fa07b7947dc23fba730d57625999311f088f6093 Mon Sep 17 00:00:00 2001 From: pauldin91 Date: Tue, 9 Jan 2024 19:22:44 +0200 Subject: [PATCH 8/9] Revert "remove activator usage from Send methods, and use new and compiled expressions for constructing RequestHandlerWrapperImpl objects" This reverts commit b7b9d28398db68d402a728c8b750c9763eddb636. --- src/MediatR/Mediator.cs | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/src/MediatR/Mediator.cs b/src/MediatR/Mediator.cs index 644dde98..4d65de18 100644 --- a/src/MediatR/Mediator.cs +++ b/src/MediatR/Mediator.cs @@ -6,7 +6,6 @@ namespace MediatR; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; using Wrappers; @@ -26,7 +25,7 @@ public class Mediator : IMediator /// Initializes a new instance of the class. /// /// Service provider. Can be a scoped or root provider - public Mediator(IServiceProvider serviceProvider) + public Mediator(IServiceProvider serviceProvider) : this(serviceProvider, new ForeachAwaitPublisher()) { } /// @@ -47,12 +46,11 @@ public Task Send(IRequest request, Cancellation throw new ArgumentNullException(nameof(request)); } - var handler = (RequestHandlerWrapper) _requestHandlers.GetOrAdd(request.GetType(), static requestType => + var handler = (RequestHandlerWrapper)_requestHandlers.GetOrAdd(request.GetType(), static requestType => { var wrapperType = typeof(RequestHandlerWrapperImpl<,>).MakeGenericType(requestType, typeof(TResponse)); - var ctor = wrapperType.GetConstructors().First(); - var expression = Expression.Lambda>>(Expression.New(ctor)).Compile() ?? throw new InvalidOperationException($"Could not create wrapper type for {requestType}"); - return expression(); + var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper type for {requestType}"); + return (RequestHandlerBase)wrapper; }); return handler.Handle(request, _serviceProvider, cancellationToken); @@ -66,16 +64,11 @@ public Task Send(TRequest request, CancellationToken cancellationToken throw new ArgumentNullException(nameof(request)); } - var handler = (RequestHandlerWrapper) _requestHandlers.GetOrAdd(request.GetType(), static requestType => + var handler = (RequestHandlerWrapper)_requestHandlers.GetOrAdd(request.GetType(), static requestType => { - try - { - return new RequestHandlerWrapperImpl(); - } - catch (Exception) - { - throw new InvalidOperationException($"Could not create wrapper type for {requestType}"); - } + var wrapperType = typeof(RequestHandlerWrapperImpl<>).MakeGenericType(requestType); + var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper type for {requestType}"); + return (RequestHandlerBase)wrapper; }); return handler.Handle(request, _serviceProvider, cancellationToken); @@ -110,7 +103,7 @@ public Task Send(TRequest request, CancellationToken cancellationToken } var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}"); - return (RequestHandlerBase) wrapper; + return (RequestHandlerBase)wrapper; }); // call via dynamic dispatch to avoid calling through reflection for performance reasons @@ -143,7 +136,7 @@ public Task Publish(object notification, CancellationToken cancellationToken = d /// The notification being published /// The cancellation token /// A task representing invoking all handlers - protected virtual Task PublishCore(IEnumerable handlerExecutors, INotification notification, CancellationToken cancellationToken) + protected virtual Task PublishCore(IEnumerable handlerExecutors, INotification notification, CancellationToken cancellationToken) => _publisher.Publish(handlerExecutors, notification, cancellationToken); private Task PublishNotification(INotification notification, CancellationToken cancellationToken = default) @@ -152,12 +145,13 @@ private Task PublishNotification(INotification notification, CancellationToken c { var wrapperType = typeof(NotificationHandlerWrapperImpl<>).MakeGenericType(notificationType); var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {notificationType}"); - return (NotificationHandlerWrapper) wrapper; + return (NotificationHandlerWrapper)wrapper; }); return handler.Handle(notification, _serviceProvider, PublishCore, cancellationToken); } + public IAsyncEnumerable CreateStream(IStreamRequest request, CancellationToken cancellationToken = default) { if (request == null) @@ -165,11 +159,11 @@ public IAsyncEnumerable CreateStream(IStreamRequest) _streamRequestHandlers.GetOrAdd(request.GetType(), static requestType => + var streamHandler = (StreamRequestHandlerWrapper)_streamRequestHandlers.GetOrAdd(request.GetType(), static requestType => { var wrapperType = typeof(StreamRequestHandlerWrapperImpl<,>).MakeGenericType(requestType, typeof(TResponse)); var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}"); - return (StreamRequestHandlerBase) wrapper; + return (StreamRequestHandlerBase)wrapper; }); var items = streamHandler.Handle(request, _serviceProvider, cancellationToken); @@ -177,6 +171,7 @@ public IAsyncEnumerable CreateStream(IStreamRequest CreateStream(object request, CancellationToken cancellationToken = default) { if (request == null) @@ -195,11 +190,11 @@ public IAsyncEnumerable CreateStream(IStreamRequest).MakeGenericType(requestType, responseType); var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}"); - return (StreamRequestHandlerBase) wrapper; + return (StreamRequestHandlerBase)wrapper; }); var items = handler.Handle(request, _serviceProvider, cancellationToken); return items; } -} \ No newline at end of file +} From d713d474b647db55d17ca99f943f47a074140036 Mon Sep 17 00:00:00 2001 From: pauldin91 Date: Tue, 9 Jan 2024 20:08:09 +0200 Subject: [PATCH 9/9] Revert changes and keep new construction in Mediator.Send --- src/MediatR/Mediator.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/MediatR/Mediator.cs b/src/MediatR/Mediator.cs index 4d65de18..09b4d56a 100644 --- a/src/MediatR/Mediator.cs +++ b/src/MediatR/Mediator.cs @@ -64,16 +64,14 @@ public Task Send(TRequest request, CancellationToken cancellationToken throw new ArgumentNullException(nameof(request)); } - var handler = (RequestHandlerWrapper)_requestHandlers.GetOrAdd(request.GetType(), static requestType => + var handler = (RequestHandlerWrapper) _requestHandlers.GetOrAdd(request.GetType(), static requestType => { - var wrapperType = typeof(RequestHandlerWrapperImpl<>).MakeGenericType(requestType); - var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper type for {requestType}"); - return (RequestHandlerBase)wrapper; + return new RequestHandlerWrapperImpl() ?? throw new InvalidOperationException($"Could not create wrapper type for {typeof(TRequest)}"); }); return handler.Handle(request, _serviceProvider, cancellationToken); } - + public Task Send(object request, CancellationToken cancellationToken = default) { if (request == null)