MediatR
MediatR copied to clipboard
MediatR Design philosophy question
In MediatR we define a command like:
public class Ping : IRequest<string> { }
and the corresponding handler like:
public class PingHandler : IRequestHandler<Ping, string>
{
public Task<string> Handle(Ping request, CancellationToken cancellationToken)
{
return Task.FromResult("Pong");
}
}
Awesome! But...
What is the reason why we need to provide the return type twice? (string in the example above)? Is it for a technical internal reason or for "readability/usability?"
Would it not be enough to provide it only in the IRequestHandler? or is it just for convenience to have it in both places?
I think IRequest as a command, so need a response as a outcome, The simplest return is true or false. If you don't care response or result, you can inheritance INotification and INotificationHandler. See the following code, please
/// <summary>
/// Marker interface to represent a notification
/// </summary>
public interface INotification { }
/// <summary>
/// Defines a handler for a notification
/// </summary>
/// <typeparam name="TNotification">The type of notification being handled</typeparam>
public interface INotificationHandler<in TNotification> where TNotification : INotification
{
/// <summary>
/// Handles a notification
/// </summary>
/// <param name="notification">The notification</param>
/// <param name="cancellationToken">Cancellation token</param>
Task Handle(TNotification notification, CancellationToken cancellationToken);
}
thanks, yes, I know its a type of command, I was just more curious about why we need to have the return type in two places... that means I need to update two places when I want to change the return signature.
So, I just thought why is it not enough to have it IRequestHandler?
I think this is certain rules for compile time validation.
I think this is certain rules for compile time validation.
That is correct. It prevents you from creating a public class PingHandler : IRequestHandler<Ping, int>
because Ping
is a IRequest<string>
.
One could argue that it doesn't actually work. There's nothing stopping me (at the API level) from defining a message as class Ping: IRequest<string>, IRequest<int>
with the expectation that I'm allowed to create two request handlers and choose which I want to use when I invoke Send
.
(I think there are runtime checks preventing this, but I'd have to read the code again to know for sure.)