MediatR and Blazor Server?
Note: Razor Components is now called Blazor Server. Bear that in mind as you read on!
With MediatR we can create ASP.NET controllers which stick to their core responsibilities (handling incoming requests, returning responses etc.) and delegate to MediatR to “trigger” business logic (commands and queries).
In this case, we fire off the query to list all users then return the results with our View.
Whilst investigating Razor Components it lead me to wonder if MediatR would work in this context too.
By way of example, here’s a Razor component (taken from the the default new starter project I touch on here) whose sole purpose is to retrieve and display weather forecasts.
This code will run on the server. On load it will invoke the ForecastService
to retrieve weather forecasts, passing in today’s date.
Unlike the ASP.NET MVC approach, we don’t need to return data with a view, we can just update the forecasts
property and the ASP.NET Core will update the UI using the new data.
Adding MediatR to the mix#
You’ll need to bring in a couple of packages to add MediatR to the project.
This means we can now register any MediatR handlers we have in our project with one call in startup.cs
.
To migrate the forecasts logic over to MediatR we’ll need to create an equivalent handler, here’s mine…
To invoke our handler we’ll need to call mediator.send
and to do that we we need to inject an instance of IMediator into our Razor Component, just as we would our MVC controllers.
Now we have access to Mediator
so we need to modify our component’s code to call Mediator
instead of ForecastService
.
I’ve removed the forecasts
property and replaced it with a property for the Model returned by our Mediator call (ListAll.Model
).
This model includes a Forecasts
property so now we just need to tweak the razor template to look there for the forecasts.
Gotchas#
The only thing that really caught me out when setting this up was that I originally called the ListAll
class (which holds our MediatR request and response) List
.
However, this then clashes with the Razor Component itself because it is also called List
and both classes exist in the same namespace (folder).
If anyone can think of a way round this whilst still keeping the function and handler in the same folder, let me know!
Save yourself some keystrokes#
If you’re going to use MediatR for most/all of your components and pages, you can skip adding @inject IMediator Mediator
to every individual .razor file by adding it to _ViewImports
file instead.
Now every component or page will have access to a Mediator
property.
I’ve put the code on Github so check that out to see how this all comes together
Legacy .NET web apps causing you grief?
Build modern, reliable web applications, faster with .NET and Blazor.
Build better .NET web apps