allReady
allReady copied to clipboard
Upgrade to MediatR 3.0
cc @tonysurma @dpaquette @stevejgordon @MisterJames
I've been doing some research into what it will take to upgrade the project to MediatR 3.0. There are breaking API changes that cause a lot of code to have to change, plus an annoying default parameter that was added to each method on IMediator which makes any mocked call to .Send or Publish non-compilable in our unit tests.
Here is what we get with version 3.0 of MediatR:
- new, simplified API where async vs. sync is only differentiated in the interface implemented in handler code. Not only is IAsyncRequest/IAsyncNotfication gone, but .SendAsync and .PublishAsync are gone as well.
- ASP.NET Core is now a "first class citizen" of MediatR. There is a new way to register and plug the Mediator into an ASP.NET Core project/container.
- Pipeline Behavior is now a "first class citizen" of the framework. Before, you had to jump through some hoops to get a custom pipeline built, and the examples out there did not support ASP.NET Core. When I asked Jimmy Bogard about how to wire up custom pipeline handlers in ASP.NET Core, he replied to used MediatR 3.0. Think of pipeline behavior as action filters for MediatR handlers. We've already seen in our system where this type of customize-able pipeline can help us with cross-cutting concerns for handlers.
Here is a list of what needs to be done:
- upgrade MediatR NuGet package to version 3.0
- track down, and change all instances of
.SendAsync
to.Send
- track down, and change all instances of
.PublishAsync
to.Publish
- track down and change all instances of
IAsyncRequest
withIRequest
(use match whole word on this one for find/replace b/c we do not want to change the name ofIAsyncRequestHandler
) - track down and change all instances of
IAsyncNotification
withINotification
(use match whole word on find/replace) - track down and change all instances of
AsyncRequestHandler
withIAsyncRequestHandler
(AsyncRequestHandler
has been deprecated). This change gets rid of the weirdprotected override void HandleCore
signature on command handlers that don't return a value - as a result of the
AsyncRequestHandler
toIAsyncRequestHandler
refactoring, change all instances ofprotected override async Task HandleCore
topublic async Task Handle
. - all calls to mediator interface needs to be updated to be awaitable
-
and the big one, append,
, default(CancellationToken)
onto any mocked call to.Send
or.Publish
in our unit tests.
All of the above changes are easily achievable using Visual Studio Find and Replace except for item 7. For item 7, I've written a file/string parser that will go through and append , default(CancellationToken)
to any mocked call to .Send
or .Publish
. I'm still testing it locally, but have already had successful replacements on unit test and those tests have compiled and run successfully.
Anything that's left over can be easily fixed by hand.
Between the breaking API changes and some of the more nitty-gritty test code changes that need to take place (items 6 and 7), we're looking at changes over at least 75% of the codebase.
So most likely, this upgrade will need to be part of some type of PR merging "freeze" so this one, massive PR can hit the system and be merged.
@mgmccarthy hey this is a good write up on some cool features in the next version of MediatR. Is the any documentation on how the interfaces for the pipelining will work? I didn't see anything about it on mediatR wiki or samples section?
@chinwobble, this is a great question and I should have included some links in the initial comment of this Issue.
Here is the official release page for MediatR 3.0: https://github.com/jbogard/MediatR/releases/tag/v3.0.0
Here is a description on how the built in pipeline behaviors work and how you can wire up your own: https://github.com/jbogard/MediatR/wiki/Behaviors
and here is a great blog about how to work with MeditR 3.0 behaviors and how to register it in ASP.NET Core http://codeopinion.com/mediatr-behaviors/
Also, did you want to finish up the unit tests for Issue #1579 or is @forestcheng currently finishing those up?
Thanks!
@mgmccarthy . Thanks for providing the links.
Regarding #1579 I haven't heard anything from @forestcheng. I'm okay to finish them if needed.
@chinwobble, thanks!
Ok, this is an old issue! MediatR 4.0 is now out https://github.com/jbogard/MediatR/releases/tag/v4.0.1
I thought there might be a few tricks to help with the refactoring. These would be temporary changes to allow for doing VS refactoring changes instead of poor man's Find & Replace.
-
Create extension methods to shim between SendAsync and Send and PublishAsync and Publish. Then the package can be upgraded to version 4.0 and these calls won't break. The code can then be progressively migrated from SendAsync to Send and PublishAsync to Publish.
-
For IAsyncRequest moving to IRequest another shim would be to define an interface IAsyncRequest that inherits from IRequest. The same for IAsyncNotification and INotification, and AsyncRequestHandler and IAsyncRequestHandler
Is there anything stopping us from doing a "find/replace" solution? The thing with creating temporary solution and then upgrading progressively can be that the temporary solution becomes permanent (or maybe it says more about some of the projects I've been working on...).