Is there any plans for a migration guide, noticed Task<Unit> being used since the latest update. Current Wiki documentation doesn't mention anything as of yet. Noticed the release is very new so potentially in the works?
More than happy to chip in if I can help anywhere.
@TheRubble you can get rid of the Unit (specifically return Unit.Value) in handlers by using AsyncRequestHandler<Request>. Other places you'll ever encounter the Unit are IMediator.Send that returns Task<Unit> and calling handlers without MediatR in tests - no big deal.
@jbogard What I don't understand though is where the AsyncRequestHandler<Request, Response> did go? It's absence now forces devs to use AsyncRequestHandler in one handlers and IRequestHandler in others - one more illogical thing for a new dev on the project to learn. Any plans to return it?
Seems like it's trying to keep everyone away from overriding RequestHandler and AsyncRequestHandler?
Speaking of that, I have a question that may be related. Say some of my backend functions don't have async, or not worthy of async/await operation, what the preferred implementation should be?
public class SyncHandler : RequestHandler<Ping, string> {
protected override string Handle(Ping request) {
return "Pong";
Or
public class PingHandler : IRequestHandler<Ping, string> {
public Task<string> Handle(Ping request, CancellationToken cancellationToken) {
return Task.FromResult("Pong");
Or
public class PingHandler : IRequestHandler<PingRequest, string> {
public async Task<string> Handle(PingRequest request, CancellationToken cancellationToken) {
return "Pong";
I'm currently overriding RequestHanlder from 4.x, but keeps reading that you should not mix sync/async. Some of my filters are async, so not sure if everything done perfectly.
Thanks.
I would say it's not really a problem to call sync code from async. The problem is the other way around since the possibility of deadlock of the context synchronization.
Your first 2 examples are almoust the same, due to how the RequestHandler is built.
The last one you do get a warning from Visual Studio if I'm not mistaken, but it's also valid.
If choosing any, I would go for the middle one, the one that returns Task.FromResult("Pong"); and implements the interface directly. I think it's the most flexible one.
https://github.com/jbogard/MediatR/wiki/Migration-Guide-4.x-to-5.0
If there's anything missing, please edit that page.
Just to summarize the changes, there are 2 main flavors of requests: those that return a value, and those that do not. The ones that do not now implement IRequest<T> where T : Unit. This was to unify requests and handlers into one single type. The diverging types broke the pipeline for many containers, the unification means you can use pipelines for any kind of request.
It forced me to add the Unit type in all cases, so I've added some helper classes for you.
IRequestHandler<T> - implement this and you will return Task<Unit>.AsyncRequestHandler<T> - inherit this and you will return Task.RequestHandler<T> - inherit this and you will return nothing (void).For requests that do return values:
IRequestHandler<T, U> - you will return Task<U>RequestHandler<T, U> - you will return UI got rid of the AsyncRequestHandler<T, U> because it really wasn't doing anything after the consolidation, a redundant base class.
Most helpful comment
@TheRubble you can get rid of the Unit (specifically
return Unit.Value) in handlers by usingAsyncRequestHandler<Request>. Other places you'll ever encounter the Unit areIMediator.Sendthat returnsTask<Unit>and calling handlers without MediatR in tests - no big deal.@jbogard What I don't understand though is where the
AsyncRequestHandler<Request, Response>did go? It's absence now forces devs to use AsyncRequestHandler in one handlers and IRequestHandler in others - one more illogical thing for a new dev on the project to learn. Any plans to return it?