asp.net core - MediatR (CQRS) Tutorial & Tips
HTML-код
- Опубликовано: 8 сен 2024
- In this video I explain how the MediatR package works and how I like to use it.
Patreon 🤝 / raw_coding
Courses 📚 learning.raw-c...
Shop 🛒 shop.raw-codin...
Discord 💬 / discord
Twitter 📣 / anton_t0shik
Twitch 🎥 / raw_coding
👉 Try Rider
www.jetbrains....
RD5K9-4TXXW-KMV3G-NYWSF-3ZSTP
Presentation By Jimmy Bogard (Creator of MediatR) - • Vertical Slice Archite...
Presentation by Jason Taylor (Clean Architecture with ASP.NET Core 3.0) - • Clean Architecture wit...
Videos by Nick Chapas - • Clean ASP.NET Core API...
My video about Middleware: • In/Out Middleware Expl...
Source: github.com/raw...
#csharp #aspnetcore #mediatr
For anyone that likes the Response message wrapper, checkout F# and functional programming, the programs are written using those with much nicer usage pattern (imagine the whole program using LINQ)
and if you don't like being constrained by types and have easier access to meta programming try Clojure
This tutorial makes it easy to grasp concepts better from the bottom up. I am now improving a lot with MediatR. Great work!!
Thank you for watching!
clear and to the point. I like the wrapper implementation; it makes it easier and cleaner. Just wanted to highlight that it is useful to use .publish () method when you are working with microservices or distributed systems. Keep it up
Awesome thanks :)
very nice. Like the casual style you have to teaching this
Thank you)
Finally youtube has suggested me something valuable.
Glad we found you
Thank you for amazing content. It's make me clear. Next, I will coding :)
Thank you for watching
great tutorial, I've been struggling with mediatr for some time now I have a clear idea about how it works, in my case I was a bit lost when you mentioned and described the pipe stuff I will look for more information about it to understand it better, thanks for this explanation, nice stuff, keep it up!!!
Cheers
Wow, the UserId thing is exactly what I've been trying to solve now, thank you so much
Concepts nicely explained...
Cheers )
amazing Anton as always!!!! You've explained something so hard easily....
Thank you )
Thank you. Learnt and applied. Easy to understand with ur examples
thank you for watching :)
Although I personally hate MediatR, I want to thank you for sharing example of Pipes. They seem to mimic .NET Core middlewares, so do not seem to bring nothing to the table though.
Yep it’s similar to middleware, though it’s at application level. When the time comes to move your app from server framework to other (Which I think will never come) you just move the mediatr calls. Just a matter of what framework you choose to lean on, but mediatr gives you portability
Learned something new, thank you so much!!
glad you did!
On a good day you will find this type of video. Thanks a lot.
Thank you for watching!
Great tutorial, not only just MediatR you also taught other programming stuff.
Chee
Hello, thanks for sharing, Great explanation
Cheers
Great! A simple explanation. Thank you!
Thank you
Nice Video. You even taught me Advanced generics with the Wrapper classes :)
Thank you, glad to hear )
Thanks for this video mate, really helpful. Especially the user id pipeline. I've been thinking how to deal with that user id claim for some time, and you showed me the way :) Much appreciated!
Glad to hear, thanks for watching
Great. Keep going
Cheers
Thanks!
Thank you!
Excellent !!! You made it look so easy...
it's not hard once you've used it for a while
Hey man, just stumbled on your channel and really like your way of explaining. Real smooth and well explained. Great stuff and keep it up!
Thank you:)
really loved that
keep up the good work my dude
Thank you for watching
Very nice tutorial, just a little question , Suppose your PipelineHehaviour you are doing validation. How do you manage Response type. How the DI work with this object when we do DI registration?
We don’t you create this response
@@RawCoding Sorry, i did not understand. I tried your tutorial with Response . I am getting issue with PipelineBehaviour in DI.
This is my DI
services.AddTransient(typeof(IPipelineWrapper), typeof(ValidationBehaviour));
///////////////////////////////////////////////
public class ValidationBehaviour :IPipelineWrapper
{
private readonly IValidationHandler validationhandler;
private readonly ILogger logger;
public ValidationBehaviour(ILogger logger)
{
this.logger = logger;
}
public ValidationBehaviour(ILogger logger, IValidationHandler validationhandler)
{
this.validationhandler = validationhandler;
}
public async Task Handle(TIn request, CancellationToken cancellationToken,
RequestHandlerDelegate next)
{
}
}
///////////////////////////////////////////////////
public interface IPipelineWrapper : IPipelineBehavior
{
}
//////////////////////////////
public class Response
{
public static Response Failed(IEnumerable message, T data = default)
=> new Response(data, message, HttpStatusCode.InternalServerError);
public static Response OK(T data, IEnumerable message = default,
HttpStatusCode code = HttpStatusCode.OK)
=> new Response(data, message, code);
}
/////////////////////////
public sealed class Response
{
public Response(T data, IEnumerable message,
HttpStatusCode code)
{
Data = data;
Message = message;
Code = code;
}
public T Data { get; set; }
public HttpStatusCode Code { get; set; }
public IEnumerable Message { get; set; }
}
/////////////////
Please share that code on my discord server in the need-help channel
@Raw Coding The issue is some what similar to github.com/jbogard/MediatR/issues/466 , But here it is asking to change DI. Is this wont work in MS DI
@@RawCoding Sure
Great tutorial i can't wait to toy around with this
Cheers, yeah this one is quite fun to use :)
This video is gold, clear explanation. Appreciate your efforts Anton.
What's your source to study?
Ty and I use the internet
@@RawCoding we all use the internet but you are on a different level. :)
Thanks a lot for this amazing tutorial man :)
Thank you for watching)
Amazing tutorial, much love for you bro :D
Thank you for watching
хороший урок, молодец.
Пасиб
What is the 'box' we trying to make portable(portify?) ? Moving the business logic to a framework other than ASP.NET Core?
Also, I m unsure what advantage we get by having the controller action method know which query to send rather than having to know which business logic method to invoke. What was the motivation for hiding the business logic behind two additional layers of abstraction - query and handler?
Correct me if I'm wrong ! but the fire and forget I use it personally for firing the send notification or sending email to a user after some checks that the current user that executes the code don't wait until the system sends the email or notification to the user to finish the request.
You can use it like that, but what about retrying if it fails?
Really helpfull
Cheers
Love your channel man. Any video about Generics class/methods?
Not really :D
ruclips.net/video/Q1Tv7vj3Txo/видео.html
I will take a nap, then am going to go through the other resources in the description to try and find an answer for the following:
if I want to run more than one command within single database transaction, how do I go about implementing this without passing the IDbContextTransaction object around? if you have insights about this, please enlighten me :)
I was about to implement sagas to cover a use case, but I thought if I can run away with multiple DbContexts on single physical database.
Do it in the pipe
mediatr look like a useful decouple tool,thank you for this tutorial。
but i was confused by those interceptors,etc middleware,fliter,mediatr's interceptor,ioc container's interceptor,db orm's interceptor...
I recommend to watch my video on middleware, link in description
First time am seeing your tutorial video, and I must say I can't wait to take my system on a ride with this. Nice job bro 👍...
Is there any other way we can achieve this without using those nuggets packages? Cuz it seams the whole process rely on those packages...
Make it yourself
@@RawCoding LOL
Would you see making N 'Service' projects the right way to go? If you have say, 2 databases and another 'web service' as the 'data sources'. Or would you put all in one Services project. I was thinking something like Data.Services, Authentication.Services, Amazon.Services (for example)...still learning this so could be completely wrong.
I can’t recommend it because it makes sense for different projects. Some need it some don’t, abstraction takes time and you have to know if it’s worth investing.
Could you consider making a similar video explaining the Repository pattern in the future? Thank you very much for your videos!
I’ll consider
Thanks, You have helped refresh my memory for MediatR,
what shortcut/command are you doing to make those files/classes, its soo quick?
If that’s in visual studio it’s the add new files extension
@@RawCoding thanks
5:50 how you get the pop up ,and why in 32:22 the unsupported error shows up ,despite i can call an endpoint without sending anything even if it needs something , but it will just initialize the object to null
Should I return raw data from my services and wrap them in a response in my controllers or return already wrapped objects from the services? Which one would you recommend?
I don’t quite know your use case, but I’d wrap it at service level.
Hello, thanks for sharing this amazing experience, but one question:
what is the name of the FONT you are using in your visual studio?
thanks in advance
JetBrains Mono
Hello, great explanation ! I have a question. Is it worth to implement Repository pattern with MediatR pattern ? A) For real life projects B) For learning purposes. Does implementing them together makes sense, and can be used in real life web applications ? BR and thanks in advance !
For learning MediatR no, your repository should be some kinda data storage abstraction, so it makes sense if you need to change the storage provider.
Thanks sharing your experience i need to clear one thing about MediatR that how Pipeline can be configured to be run before or after the command and query ?
Hey I am pretty sure I explain that in the video. Pipe will run for all commands and queries, what I do in the video is just specify what to do if it is a command or query
@@RawCoding i think you did not get my point let me clear with an example i want to authenticate the user before processing command or query and also want to log after processing command or query how will i configure this in the DI container.
i have been working on MediatR i added validation behaviour like below and it is working perfectly fine but how mediatR know this validation should be run before processing command or query
e.g... services.AddMediatR(Assembly.GetExecutingAssembly());
services.AddTransient(typeof(IPipelineBehavior), typeof(ValidationBehavior));
Register the pipe before you register the command/query processing pipe
@@RawCoding yes even in above case i have registered after mediatR service but it is executing before command query anyways thanks :)
Can you please do a video on MassTransit project? It can be used in conjunction with MediatR. I got confused as I thought they are doing the same thing. If used in conjunction, what is the responsibility for each of the package?
Never used it so I’ll probably not cover it
thank you
Thank you for watching:D
Thanks for your video, but I have a feeling like I didn't quite understand what's the difference between middleware and cqrs pipe. They both intercept request, do some extra functional and pass to the next handler. Looks like they are interchangeable
? In which cases I'd rather implement my own middleware/cqrs pipe?
Middleware is tied to asp.net core framework the pipe is tied to Mediatr so it’s a bit closer to business logic. Let’s say you want to transfer functionality from backend to Xamarin app, you can’t shift the middleware but you can shift the pipe.
@@RawCoding aha, I'm getting it a bit..
IMHO this talk is more on asp.net core rather than MediatR.
I was looking for explanation on problems which MediatR addresses, and you numbered some in the beginning of the video, but then you just forgot about the topic.
Still worth watching thanks to a couple coding tips'n'tricks though....
Mhmm, I’d say I’m just talking about how to use it rather than when and for what problem
I have a quick question i.e. why people use MediatR with CQRS only?
Not only
Nice tutorial..pls share link for multiple list in command & handler.how to do it in mediator pattern.
Sorry I didn’t understand the question
@@RawCoding how to insert multiple list by using Mediator pattern & CQRS.
ThanX Amazing Channel, and I have Question
how to output count of objects in tables using MediatR??))
MediatR can’t do that
@@RawCoding Can I write anywhere?
@@RawCoding But MediatR can ouput List of Cars, So I just wanna Output count of Cars
If you want to get a list of cars from the database you’ll need to use some kind a provider native or dapper or ef core. In ef core for example you can .Count() on a table
@@RawCoding OK. ThanX for Answers!!!)))
Hello, at the beginning I want to thank you for making such great tutorials. I really appreciate that you're explaining everything from the grounds up.
I have got a question when it comes to implementing CQRS:
Let's say I have an MVC app. I have a BookController with Create action method. Also I have a BookViewModel cause i need to validate some of the fields. So i am passing BookViewModel to the Create method so we have Create(BookViewModel model). Then I add CreateCommand with Handler. Now I need to map between BookViewModel and CreateCommand and send this command via Mediator. Here my first question comes: Does CreateCommand replaces DTO like when I would simply use services for instance _bookService.CreateBook(bookDTO book)? If I'm right I don't need DTOs when using Commands and Queries anymore? Following along, inside CreateHandler I need to add the book, so I have to map between CreateCommand and Book domain model this time. So the second question is: Am I doing it right?
why not use CreateCommand instead of BookViewModel ? it's just a c# object that you can validate as well.
> Does CreateCommand replaces DTO like when I would simply use services for instance _bookService.CreateBook(bookDTO book)?
I don't understad DTO's. if you need an class to represent some data make it.
> If I'm right I don't need DTOs when using Commands and Queries anymore?
Again I don't know or use DTO's, if you need a class to represent some data just make it.
> Following along, inside CreateHandler I need to add the book, so I have to map between CreateCommand and Book domain model this time. So the second question is: Am I doing it right?
right in what sense? if it works it works. You will know you have a problem when your solution will become hard to maintain untill then it's hard to say if you are doing something right without seeing the rest of the system.
I generally think this is enough (try to have as little intermidiate objects as possible)
public void Do(CreateCommand command){
...
_ctx.Books.Add(new Book {
Title = command.Title
...
})
...
}
Thank you for the response.
From what you said I understand that I should just keep it simple.
>right in what sense? if it works it works. You will know you have a problem when your solution will become hard to maintain untill then it's hard to say if you are doing something right without seeing the rest of the system.
In architectural sense. I just wanted to know whether it's a good design flow assuming that we need a separation of concerns (viewmodel strictly for ui purpose, dto to pass only required data, and model for a database). I know it may seem too sophisticated and I could simply use one class for data representation but don't you think that implementing CQRS is also just making our app more complicated?
I am sorry for stupid questions, I think's that's because I am beginner yet and just want to make a good software and get simple answers how to do that.
Greetings from Poland:)
Not stupid question at all, I’d recommend to 1st keep it simple and only after try to predict realistically where do you need the separation to add the extra classes
nice
thank you for watching
👍🏽
)
Why would you use such wrapper around your responses?
If there is an error, indicate that with a 400 or 500 HTTP code. Why the need for bool error?
Im not sure I understood the reasoning for the message property about translations??Isnt the data itself the message?
business logic -> other things -> framework -> http -> client
the reality is your business logic sits quite far away from http, this wrapper is just a way to bring "structured response" closer to business logic so we can capture it and then the client can have common logic for processing the responses.
@@RawCoding but rather than modifying how an intermediate result is presented to the business logic, in this particular case we are modifying how it is sent to the external client living outside our application. we are sending back a 200 response indicating success in the header, but a boolean in the body suggesting failure.
are there cases common use cases where the client would benefit from this kind of response?
thanks for your response though
Do I have to pass cancellation token from controller into send method or MediatR takes care about it by itself?
Mediatr takes care of it
@@RawCoding thanks again
This is great! Just want to ask what was wrong with my implementation on the Respons. I copied the response.cs. How comes I am not able to access the Ok and Failed method? : IRequest , then in the command handler says Response does not contain Ok definition. Did I miss anything to implement?
Mhm not sure maybe your missing a using statement
What is MediatR doing for me over just my own injected service? Just c#
Super..
Cheers
I'm curious if you are aware of work done with Code Gen techniques to stub out a set of queries and handlers based on a given api?
Create custom templates, or swagger
@@RawCoding Custom templates. It's been a few months but I think I'd seen a presentation by someone outlining an end-to-end code gen strategy where even the unit tests were part of the code generation stream.
Umm yea not aware of that
Do you have a real-world example tutorial of this?
No
Hi, first at all, this is a nice example. I have a question related to the example at 25:24: I think UserId parameter has been added to the request. So if you are using Swagger you will see a new parameter exposed to the clients, but this value is calculated in the pipeline. Is it possible to hide it or just mark it as calculated?
Well, after thinking a bit, the solution was declare abstract to BaseRequest ;)
Not sure what you mean
@@RawCoding Hahaha! No worries. I can try to explain it better... In BaseRequest class you have added a new property (UserId). It means that all the clients of this Query (Can't remember if it was on Query or command example) could set UserId during the request. I was wondering how to hide UserId parameter from the clients because it is filled in the Pipeline.
What do you mean hide UserId from the clients?
@@RawCoding Let´s say you want to use GetAllCarsQuery in another Controller. You could do something like this: mediator.Send(GetAllCarsQuery { UserId = 1 }). So, my question was how to make this attribute not accessible for classes that use this Query.
Is there a way to handle a mediator object from becoming a God object?
What do you mean?
@@RawCoding What I read about mediator pattern is that in a complex application, the dependency on the mediator object increases, and it becomes God object (when object knows too much or does too much). How to avoid that scenario?
Dependency inject business logic and use handlers as proxies.
@@RawCoding Can you explain a bit further? by giving any example?
The same way you don’t want your logic in the controller and put it in the mediatr, now you don’t want it in mediatr just put it somewhere and inject the logic in to handlers
Is there any way to register behaviorPipe on sending the command?
cause from my understanding behaviorPipe gets executed with each mediator.send()
so with bigger projects i am going to end up with 20-30 pipes that get executed with every mediator.send().
Let's say i create only one pipe for authorization that gets all the validation objects and then checks the types chooses the right ones.
But what about custom validatiors that need to call db. How will dependency injection work with all the authorization classes and dbcontext and pipes. Am i going to end up with a memory leak or something? Do you have maybe some blogs or videos that tackle that sort of problems?
> Is there any way to register behaviorPipe on sending the command?
Just inlcude that functionality in the command it self
> so with bigger projects i am going to end up with 20-30 pipes that get executed with every mediator.send().
dubt you will be able to reach 20-30 I will be suprised if you can give me 10 use cases for using the pipeline.
> But what about custom validatiors that need to call db. How will dependency injection work with all the authorization classes and dbcontext and pipes.
It should just work
> Am i going to end up with a memory leak or something?
As long as you lean on the DI, no
Can MediatR update Database ?
I can't do that. Help me.
Sorry, my English
Mediatr is not meant for that. It’s just to call a handler - your handler then needs to save to database
Nice work. Do you think Mediatr is also suitable for simple logic checks that's not CRUD? Its a query after all, but does it deserve the boilerplate for the pattern. I'm not going to return a DTO here, it may be a simple yes/no question to the API that will guide the logic from the client side to decide how to proceed with the app. And if not, what is the best practice here?
Sorry I don’t understand your question.
@@RawCoding I practiced the Mediatr pattern in a project that has the typical clear architecture structure of project where there is a dotnet core API project with controllers and an Application project for the business logic where MediatR is used. On the client side I'm using React and Mobx. For the usual CRUD part of the system MediatR is very fine and in case of Queries I send one object that is usually a parameter(s) list and get back - using AutoMapper - a DTO or whatever I need back from the DB. My question is, while i'm on the client side I need a small piece of info from the API that will direct the flow of the program - e.g. display React component A or B - is it ok to use MediatR also for such query or just do that in the controller for example. I'm not sure if MediatR is the right choice to get that info from the DB as we're not returning business objects here it maybe just a yes / no flag! What do you think. I hope I'm clear this time. Or maybe in other words, shall you use CQRS for all communications with the DB or maybe there are other patterns to consider in my case? Thanks for your time.
Mediatr can be used for this yes. Although I still don’t understand why you specifically need Mediatr
I need it to standardise on cqrs for the whole app. Maybe an example will make it clearer if you allow me. I have a grid that shows a list of parties and there is a parties table. The party can either be a person or a company and there are tables for each connected to the main parties table that just contain the common properties of each party. When the user click on a partyid in the grid I want to navigate to a full record screen showing either a person or a company and I use mediatr for that. The point here is that I can pass the partyid to mediatr and determine the party type inside the handler but mediatr need to know what response object type it needs to return and at that moment I still don't know yet. I'm not sure what is the best solution here. Shall I make two calls to the api. One to determine the party type and decide based on that. And if the first check deserve to have a mediatr call by itself to know the part type or what!! Appreciate your help.
So you can put partyid and partytype in the url query, what does this have to do with mediatr?
how can integrate the database in this architecture
Inject it in to your handler
@@RawCoding there's a any demo there?
It’s standard dependency injection in dotnet core, if you don’t know anything about dotnet core watch my blog series
@@RawCoding sure thank you I will follow your blogs
Can i have more than one handler for the request
if no can you please make other one for the publish event to the event bus and subscribers for that event :)
Don’t think you can, I would make a single handler that calls the other 2
Hi, what is the font name you use ?
JetBrains mono
@@RawCoding Thanks
Hello, Thanks for sharing this excellent video. I have a question on how to use MediatR command within the angular component. looking for any sample or link.
I'm not sure what you mean. Just have your controller send a command to the API which MediatR can process
The scope of CQRS and Mediatr(library) is limited to server-side code. In Angular, half of the job(event-based communication) is already done when you use Observables, CQRS is completely dependent on how you shape your models.
ASP.NET Core MediatR error: Register your handlers with the container
could you pls debug me this error
You haven’t specified where to load handlers from
Quick tip: normalize your audio tracks. Your volume is very low.
Yup thanks
Is any other architect there if yes pls specify me that
What?
@@RawCoding like mediatr design pattern architect like that
Singleton
Very Nice video Sir, what is your name :)
Thanks, and it’s Anton
Really liked the last generic part.
@@RawCoding can you make video in docker with .net core api or with anything?
also if you can have a video design patterns that you use often would be really helpful sir 🙂
Mmmm maybe some time in the future
"public class GetAllCars".... are you serious? I thought the classes are to describe entities, not behaviors.... "public class GetAllProductsFromNewYorkCity"
Some classes are to describe dumb data (entities). Some classes exist purely to hold functions (behaviour). It's generally bad idea to have a hybrid of the 2 - smart data, you don't want this because it harms your reasoning around the code base. Look up Data Context Interaction
0...