Unlocking Easy-Mode Mediator Pattern With MediatR
December 4, 2023
• 911 views
In this video, we'll explore how to use Mediatr for the Mediator Design Pattern. Mediatr is a popular nuget package used for communicating between different components/systems. If you're looking to learn how to use Mediatr for the Mediator Design Pattern, then be sure to watch this video! After watching this video, you'll be able to understand and use the Mediator Design Pattern with ease leveraging Mediatr!
Have you subscribed to my weekly newsletter yet? A 5-minute read every weekend, right t...
View Transcript
if you've been building applications in asp.net you've probably come across mediator at some point in your travels there are plenty of other content creators talking about how they're using mediator in their asp.net core web apps in order to have different pieces communicate with each other so like I was showing in my last video which if you haven't watched I'll link it right up here for you to watch and then come right back we were talking about the mediator design pattern and how that allowed for different pieces of a system to communicate with each other without necessarily being coupled to each other there's effectively a man in the middle which is the mediator and this allows for the different parts of the system to talk to that man in the middle which then talks to the other parts of the system in this video we're going
to look at the nou get package mediator which is really popular for being able to support this type of communication pattern and a quick reminder before I jump over to visual studio is to check out my weekly software engineering newsletter it's totally free no strings attached and I'll have a link in the pin comment below all right let's check out some code on my screen I have a sample application that's using mediator to build effectively what we saw in the last video and if you haven't gone and watched that that yet it's a really really simple chat room or chat group application it's very contrived so it's not something that's going to run over the network currently but it allows us to add several users which you can see right here register them onto this registar and then from there they're able to communicate with
each other and we're going to explain how this all works but before I jump into this particular code I want to show you the Nate packages that you're going to need to use to do this so I've just gone ahead and open up the CSR file to show you these nougat package references and I wanted to take a moment to call out that if you go looking up this information online I've noticed that there's a handful of Articles and different stack Overflow posts that have some of this information incorrect so we only need these two nougat packages in particular if we're building a console application or something that's not necessarily asp.net core that we want to have mediator hooked up for so in order to get mediator hooked up we need mediator itself so we're going to reference that n package depending on when you're
watching this video video there might be other versions available for you and the other thing that we're going to need to Leverage is the Microsoft extensions for dependency injection if you're using asp.net core I believe that you get all the dependency injection stuff you need right out of the box and you likely only need this Nate package however because I'm going to demonstrate this in a console application I just want to call out that you're going to want to have both of these all right so heading back over to the program I just want to show you that we need to wire up some dependencies how all of that looks and then we're going to walk through the different implementation that we need with mediator so the different sections of the program that I have sectioned out with this console right line just to be
able to see on the console what's going on first of all we're going to create this service collection and if you're familiar with the dependency injection framework in Microsoft I don't really need to explain this part to you however we are going to have a message Handler and a regist that we're working with and we're going to dive into those in just a moment but the part in particular that we need to make sure we're doing is adding this mediator service configuration and what I was mentioning just a little bit earlier is some of the information online is incorrect for this in fact if you go ahead and ask chat GPT like I tried doing you're going to notice that it's giving you incorrect recommendations unless you keep poking and prodding it and that's because this ad mediator method seems to have changed previously it
was just taking in this parameter right here and we call the method just like this however that's not the case anymore and I'm not sure what version that changed in but we're able to get the same thing that we need just by having this syntax here from line 9 to 12 at this point once we've executed all of this code we end up having a service collection that's created for us and we're able to resolve those services so in the next part I'm getting all of the different pieces that we need to put this all together so I'm going to ask for an IM mediator which is created thanks to the mediator nougat package and then I'm going to resolve these two classes here and I'm going to have to explain these to you in a little bit more detail which we'll do in just
a moment but these are the classes that we're making for this particular program to run once we resolve these three services that we need to work with we're going to go ahead and create three different users and because this is just a contrived example we could do two users up to 10 users or whatever number of users we want to work with and then we need to register them onto this user registar and in just a moment like I said I'll explain what this part does and I'll come back and re-explain this very briefly the last part of our program here is just going to send out the messages and we'll see what happens when the receivers end up dealing with those okay so first I want to start with the user Reg because I mentioned that we needed to register users but we didn't
really explain what was happening with them this user registar is just something to maintain state for us and we're going to see in just a moment but when we're dealing with mediator the state of the Handler that we have isn't maintained and that's going to make more sense in just a moment so the sole purpose of this user register class is just to keep track of the different users in our system that's it it's super simple and then we have a property to expose that so other people can see that so in our example that we just looked at that means we're going to be adding three different users into here through this method and then when we ask for the collection of users we'll be able to get all three back okay so what does a chat user look like well the chat user
is going to take in an imediator reference as well as a name that we want to give it and again just a quick reminder that our chat users are not going to be talking directly to each other that's more like an observable pattern or something else where we have direct coupling to the things that want to communicate in our particular instance we want to talk through a mediator so the chat users don't know about each other there's no coupling to the particular type that they want to send to and all that they know is how to communicate with the mediator the mediator is the only API they have to communicate with and the mediator handles that communication on their behalf so when we jump back to the code I hope that clarifies it a little bit more that's why each user doesn't have a reference
to all the other users it's talking through the mediator all right with our mediator reference we can check out this send message method that we have and all that we're going to be doing is taking in some text and and then creating this data transfer object that has the name so our name as the sender as well as the message that we want to send and from there just like I mentioned all that we're going to be doing is communicating through the mediator and the chat user itself also has this receive message implementation and the receive message implementation allows us to handle messages that come from the mediator so when the mediator receives a message what it's able to do from there is delegate that out to the correct receivers because our application is just a little simulated a chat room or a little group
chat that means that when we send a message it's going to get broadcast to all the other users that are attached to the registar so we have a couple of pieces that we've looked at the chat users themselves as well as the registar where they're registered to but how does the mediator come into play here and what was the other class that we were looking at well the last class that we have to look at is the I request Handler implementation that we've created and that's called chat message Handler I left a comment here because this is incredibly important when you're working with mediator to understand how this behaves this this particular message Handler when we wire it up with mediator is going to create a new instance every single time it wants to handle the message and that means that this class cannot have
any state so so I want you to pause and think for a moment because this class is supposed to handle the chat messages and that would mean that if it's handling a message it's supposed to be able to delegate that out to the other users how could it possibly do that if it can't maintain a state of all of the users if it's not allowed to have any state well fortunately our Nifty us user register is the thing that we created to do that for us so that means that every time one of these handlers is created we will get a reference to that user registar because this user registar is hooked up as a single instance that means that every single time we create one of these chat message handlers through mediator we will get that same user regist instance and I added a
console right line here is that when we go to run this you can see that in fact it will create a new chat message Handler every single time that we send a message so so quick recap this chat message Handler is created per message that gets sent it cannot have state and as a result we need to move the state into some other dependency that we can have automatically passed in through the dependency injection framework now the method that this class needs to implement according to the interface is this handle method it takes in the chat message that we're going to be sending from our chat users and has a cancellation token as well again if you watch in the previous video what we were able to do is Loop through the user registar and for each user that's in there we end up broadcasting
this message out to that user the only thing that we're doing here is skipping over the sender and I mentioned in the previous video and I'll mention it here as well that this is a little bit silly we probably wouldn't want to restrict people from having the same name instead we would probably want to check if the IDS or something were the same on the user so um this is a little bit of a hack here but just a heads up that that's why we're ignoring the sender when we go to broadcast this message out and then we're going to call that receive message method me that we looked at a little bit earlier we pass in the content of the message as well as who it came from and I'm also going to call out that I added a couple console right lines so
that when we read through this example at the end we can see all of the Behavior coming together now a quick note if you wanted different behavior for your chat application or you needed to handle messages differently this is the spot in the code in essentially your message Handler that you're going to want to change and update according to your rules that's because the chat users themselves are not responsible for communicating with each other but they need to be able to talk to this message Handler in order to have that routed accordingly okay so before we go and look at the output of this I just want to quickly skim over this one more time so we can understand it but I'm going to start right from here where we're registering users onto the services that we need so we're going to ask for the
mediator here on line 16 and that's going to be the reference that we pass into each chat user to communicate with now we register this chat message Handler above and it's already essentially hooked up with the imediator thanks to the mediator nougat package so in fact if we click on this and we look at where it's highlighted there is no use of this we actually we in fact don't need to have this included at all and that's because if you recall what I said a little bit earlier when we send messages from chat users and that goes into the mediator that mediator will instantiate a new Handler every single time and we will see that in the output but the final thing that we do need to resolve here is on line 17 that's the user register and if you recall I was say that
because we are creating that message Handler every single time we need to have something that can maintain the state that something is our user registar it tracks all of the users for us so that message Handler when it's automatically constructed through the dependency injection framework we'll get this instance and all of these three users that get registered on here will be available to our Handler and I know you want to see the output of this so let me press play and let's step through it all right so no exceptions which is great news and if we start from the top we can see that we're creating the services that wasn't too special but that's that service collection work we had to do then from there we're going to be registering the users and the first part of that is resolving those dependencies that we did
in the first step when we were creating the service next we're going to send that first message and you can see right after that we are constructing a chat message Handler and I want you to pay attention because we're going to create another one of these after we send the second message from there mediator is going to enter that message Handler and this is another console right line that I added and we can see that when we're sending the first message which came from user one that only user 2 and user 3 are handling it the text that's added here where it says user one and hello everyone is passed along as that chat message and right after that we can see that we're exiting the message Handler and that was sending the first message so let's check out the second which right here says
sending second message and like I said we're going to construct another chat message Handler so just another reminder because it's incredible important for mediator it's not maintaining state in the Handler we have to have that state somewhere else if we truly require State and in this silly example yeah we do need some state if you're communicating between different services and things like that you may not need it the same way here from there we enter the message Handler once again and we can see that user 2 and three are getting a message from user one and finally we exit the message Handler all right and that's going to wrap up the mediator pattern using mediator we saw that we had to use the service ction so the dependency injection framework that Microsoft has to register our Handler as well as pull out the mediator and
the Handler that we registered and we did need to have something else in our example to maintain state that was that user regist that we looked at once we added users to that and started sending messages that went through the mediator that Handler implementation was able to use the regist to get the users and then have them receive the message on their own method call again the important call out for this video and for the mediator pattern is effectively that the things that want to communicate with each other the chat users in this case don't have to know anything about the implementation of the receiver all they know is that they can communicate through this IM mediator and trust that they're giving it enough information for that message to get delivered this can allow us to build really decoupled systems that have messaging involved and
that's a pretty awesome thing when you're Building Systems at scale now I know you're a keen software developer and you're thinking cuz I know this is top of mind that when we have code like this how should we test it cuz that's what every software developer should be thinking right should you be using unit tests for this or should you be using functional tests well if you're not really sure and you'd like an idea where to start you can check out this video next thanks and I'll see you next time
Frequently Asked Questions
What is the Mediator pattern and how does it work in the context of this video?
The Mediator pattern is a design pattern that allows different parts of a system to communicate with each other without being tightly coupled. In this video, I demonstrate how to use the MediatR NuGet package to implement the Mediator pattern in a simple chat application. The Mediator acts as an intermediary, allowing chat users to send messages through it without knowing about each other directly.
What NuGet packages do I need to use MediatR in a console application?
To use MediatR in a console application, you need to reference two NuGet packages: 'MediatR' itself and 'Microsoft.Extensions.DependencyInjection' for dependency injection. If you're using ASP.NET Core, the dependency injection features are included out of the box, so you might only need the MediatR package.
How does the message handling work with the Mediator pattern in this example?
In this example, when a chat user sends a message, the Mediator creates a new instance of the message handler to process that message. This handler does not maintain any state, which is why we use a separate user register to keep track of the users. The handler retrieves the users from the register and broadcasts the message to them, ensuring that the chat users remain decoupled.
These FAQs were generated by AI from the video transcript.