CQRS & MediatR | ASP.NET 6 REST API Following CLEAN ARCHITECTURE & DDD Tutorial | Part 6

  Рет қаралды 64,661

Amichai Mantinband

Amichai Mantinband

Күн бұрын

Link to the full playlist: • ASP.NET 6 REST API Fol...
Become a Patreon & get the source code: / amantinband
Follow me on 'em socials:
Twitter: / amantinband
LinkedIn: / amantinband
GitHub: github.com/amantinband
What is this series?
We'll build a REST API following Clean Architecture & Domain-Driven Design principles completely from scratch.
We will use .NET 6, EF Core, and common patterns such as CQRS, unit of work, repository, mediator, and more 💪🏽
We'll also use some awesome open-source libraries such as MediatR, FluentValidation, ErrorOr, Throw, Mapster, and more.
The developing environment will be visual studio code & dotnet CLI only. We will use awesome vscode plugins for everything from sending HTTP requests to connecting to our SQL database, debugging, and peeking at JWT tokens.
We will code and refactor multiple times to tackle the many concepts I want to teach. When the series will be over, you'll have a good understanding and intuition on how to use these patterns & libraries in your industry-level applications.
How often will a new part come out?
Once or twice a week.
What are we doing today?
Today we'll split our application logic following the CQRS Design Pattern.
Then, we'll introduce the package MediatR which will play nicely with this Design Pattern and help us split our logic by feature, which will make the use cases in our application layer clear.
Give MediatR a ⭐:
github.com/jbogard/MediatR
#dotnet
00:00. CQS (Command Query Separation)
01:40. CQRS (Command Query Responsibility Segregation)
02:27. CQS & CQRS Misconceptions
03:18. Implementing CQRS
06:57. The Problem with CQRS in large systems
07:33. Splitting the logic by Feature
09:07. MediatR NuGet package
10:02. Implementing MediatR Command
11:35. Implementing MediatR Command Handler
13:07. Implementing MediatR Query
13:36. Implementing MediatR Query Handler
14:30. MediatR Dependency Injection
16:12. Using the Mediator object
16:34. Mediator pro tip
18:00. Domain Models with CQRS Query path

Пікірлер: 153
@amantinband
@amantinband 2 жыл бұрын
CQS: Method can either change state or return a value - not both CQRS: Like CQS, but not as strict regarding the return value, the main emphasis is on having a clear boundary between Commands and Queries Mediator Pattern: Promote loose coupling between objects by having them interact via a mediator rather than referencing each other MediatR: An in-memory implementation of the Mediator pattern, where MediatR requests & MediatR handlers are wired up during the DI setup Splitting Logic By Feature: Having each use case in a separate file What we demonstrated today is using the MediatR package to implement the Mediator design pattern. We separated our use cases into different files, and following CQRS, we defined clear boundaries between our Commands and Queries by nesting Command Handlers and Query Handlers in different folders. Please remember that the definitions above follow the original definitions of the people who coined the terms, not interpretations of others over the years. Hope that clears up any confusion 🙂
@sushilb7994
@sushilb7994 2 жыл бұрын
Thanks for sharing. When can we expect next video 🙂 eagerly waiting... Can you upload videos twice a week please 😀... I know this is too much to ask... This is the best content so far on the KZbin.... Keep it up....
@efimov90
@efimov90 2 жыл бұрын
12:56 isn't it better to return ValueTask.FromResult() if it is async now?
@user-wb1ip7be6u
@user-wb1ip7be6u Жыл бұрын
Update on how you should implement the DI in Mediatr starting version 12.0.0: services.AddMediatR(config => config.RegisterServicesFromAssembly(typeof(DependencyInjection).Assembly));
@redfire1205
@redfire1205 4 ай бұрын
Thank you!
@emilzyka6853
@emilzyka6853 11 ай бұрын
Hands down best explanation of CQRS I have found with non-trivial practical example to understand how it is implemented. Thank you!
@kmcdo
@kmcdo 2 жыл бұрын
I love the MediatR library. I actually didn’t know you could use just use the ISender instead of the full IMediator to get a slimmed down mediator if that’s all you use if for. Another great VOD in the books!
@sushilb7994
@sushilb7994 2 жыл бұрын
Me too. Glad to know.
@mithrilman3421
@mithrilman3421 2 жыл бұрын
good first steps in the "right" direction, when behaviours will kick in to have logging, transactions, validations, and so on. A long way to go even considering DDD but I'm sure people will enjoy the final result! Just an advice to people who are watching this series (but in general any dev video): after having watched a vid, do your own research on the topic, don't assume what you are actually listened to is good enough or a perfect fit for your needs because things will evolve next episodes and will change a lot of things, also there isn't a silver bullet so it's worth going deeper into the subjects to understand the ins and outs. You'll find yourself changing your approach every now and then: it's a sign you are learning and that's the good thing. The "bad" side is that the learning path never ends :) (actually having to learn everyday is one of the things I like the most about this job and I think every good programmer need to have this approach)
@TrOgaN_
@TrOgaN_ Ай бұрын
I'm following this course using .Net 8, so far so good. This was an enlightening section, thanks for putting it together.
@wvanlosser
@wvanlosser 2 жыл бұрын
Just found this series this week. Very interesting and informative. Much thanks for creating this series and keep up the good work!
@silvertek
@silvertek 2 жыл бұрын
I need more! This series is fantastic, cant get episodes fast enough :D
@patrykk.4630
@patrykk.4630 2 жыл бұрын
When I met the MediatR for the first time (at work in one of our projects) I was shocked how beautiful this library (and CQRS pattern of course) is. It makes Controllers so clean and small with no effort. I hope for the 'Notification' part in MediatR 😊
@TayyabMughalDIK
@TayyabMughalDIK 2 жыл бұрын
I am already loving this series
@evilTano
@evilTano 2 жыл бұрын
Your video are pure gold! Thank you! I'm switching from Game Dev to Backend development and your videos are helping me a lot. I'm also studying DDD so I can't wait to see more about!
@amantinband
@amantinband 2 жыл бұрын
Awesome to hear. Thanks, Gaetano!
@homerreal
@homerreal 2 жыл бұрын
Love your videos
@willhunt3000
@willhunt3000 Жыл бұрын
Amichal - great video as usual. Great, concise and comprehensible info.
@TiagoPereira-rf9jf
@TiagoPereira-rf9jf 2 жыл бұрын
Another amazing video, can't wait for the next one :D
@Hassanlou
@Hassanlou 11 ай бұрын
There's no doubt that the series is great, but the comments and answers are also valuable as I learn from them.
@afsanehhazeghi8890
@afsanehhazeghi8890 2 жыл бұрын
Good job as always. I can`t wait for your upcoming videos.
@nthonymiller
@nthonymiller Жыл бұрын
Thanks, this how I've been implementing my apps. So much clearer to reason about the code base.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
This is the way! 🛣🛣🛣
@DanielTames
@DanielTames 2 жыл бұрын
I really appreciate your content man! than you very much!
@Gibby78771
@Gibby78771 2 жыл бұрын
Awesome video . Waiting for other parts for DD and cqrs
@tomekmbb
@tomekmbb 2 жыл бұрын
This is so cool, I cannot wait for next one :P
@urzadek27
@urzadek27 2 жыл бұрын
The pacing is amazing for people like me who are impatient lol, seriously these videos are wonderful.
@amantinband
@amantinband 2 жыл бұрын
Haha I'm super impatient myself, which is why I like a higher pace. I'm starting to think it might be just a little too fast 👀
@rezarezash
@rezarezash Жыл бұрын
Amazing video - Many thanks
@pasindushalinda7979
@pasindushalinda7979 2 жыл бұрын
Awesome tutorial ♥️
@ugursesen7629
@ugursesen7629 2 жыл бұрын
Your trainings are great, thank you very much, we would be glad if you support these lessons with real real database.
@amantinband
@amantinband 2 жыл бұрын
We'll use EF Core with SQL in the final result 🤙🏼
@ugursesen7629
@ugursesen7629 2 жыл бұрын
@@amantinband thank you so much, you are great
@hirusalempuri3907
@hirusalempuri3907 2 жыл бұрын
I am in love with your content, wait for the next videos eagerly, when are u coming up with next videos?
@tawhidurrahman2780
@tawhidurrahman2780 Жыл бұрын
please make videos on testing, CI/CD. your explanations are awesome 👍❤
@philiphendry8008
@philiphendry8008 Жыл бұрын
Come across your videos recently and they're very good, right content and right pace from my perspective at least. I do have a question regarding the login although this is probably more applicable if the authentication services were self-implemented(which you should never do, of course, instead rely on AzureAD etc.) Something as simple as Login can still have side-effects such as incrementing a failed login count, writing an audit trail, etc. Would these be implemented in the application layer as commands whilst the consumer still regards Login as a read-only activity and is unaware of these commands running?
@gremlinx7819
@gremlinx7819 Жыл бұрын
Great video! Do you mind showing in one of the next videos maybe additional integration with DB with dapper for reading and EF for write?
@DemoBytom
@DemoBytom 2 жыл бұрын
Honest question. But what value CQRS and separating things into commands and queries actually bring? Underneath it's all just MediatR.IRequest - so they are handled exactly the same way by the command bus/Mediator. The handlers ultimatelly don't really differ. Queries, as you said in one of the comments below, can morph into commands, for example when Login Query needs to also update DB with amount of login attempts - it becomes a Command, requiring a refactor which in some cases might be a breaking change. I could see it having some value if it was, I dunno, an interface for repository - where we'd only query data from repository, or update it. But that's usually unrealistic, and Commands/Queries quickly spread into business logic (like here with Login/Create Token requests). Since Commands also return values they are, essentially better Queries anyway. Also can Query Handlers issue Commands and indirectly change values in the store? Or do they need to be refactored into Commands too now? I'm asking all that, because I'm at the tail end of massive refactor, removing CQRS from quite big service, in my company. After few years of development, we realized separating things into Commands and Queries didn't add anything, except for confusion. Queries once created weren't refactored into Commands, if a need arose, Commands sometimes acted like Queries, Queries like Commands, and it all become a massive mess. We tried enforcing restriction, by having dedicated interfaces for Commands/Queries, that restricted what they can return etc. We tried separating business logic into very granular commands/queries, but that become overwhelming - for ex. Authentication - Query for info if user can be authenticated, send Command to update it's attempt number, send query to check if a refresh token is available, if yes, send command to invalidate the token, send command to generate new access/refresh token, send query to get the tokens etc.. This become unwieldly. With so many granular commands/queries it also become increasingly hard to keep track of which are still actually used, as the development progressed.. So now we are throwing it all away, and scaling back the granularity of each MediatR.IRequest. We just have "high level" request send from API endpoint/Controller to a MediatR handler, which handles it, and if it needs more granularity - it sends more requests for other handlers to deal with. That loose coupling that MediatR provides is still there and this is great. But any separation between Commands and Queries is gone.
@CarlosHerasme
@CarlosHerasme Жыл бұрын
I was reading the comments precisely for this, I mean if someone thinks that CQRS doesn't add too much value, but unnecessary complexity, and, as you said, queries can evolve into commands depending on the business, and that, for sure, will require a more complex process of refactoring. I'm really enjoying what Amichai is doing with these videos and showing how we can do the same thing. And, for that reason, we can infer what is better to use depending on what we need. PS: Sorry for my English😅
@HaysBays-gd2lf
@HaysBays-gd2lf 9 ай бұрын
Hi mr:Amichai at 10:05 of the video you miss to say to install the mediatR package in api layer maybe you cat the video during montage. Really really really thanks for your efforts. It's a great series on KZbin. I hope to talk about Dockers and containers. Thanks again.
@LoftyCuber
@LoftyCuber 2 жыл бұрын
In the past I've used the Command Pattern as described in the GoF book to facilitate Undo/Redo in MVVM applications by keeping a list of all the command objects. If I was building a web app where I wanted a Rest API and Blazor App for different Presentation layers, would there be any relationship between the GoF commands and the CQRS commands? Could CQRS help with Undo/Redo?
@vipuldimri6571
@vipuldimri6571 2 жыл бұрын
Great Video
@Compilerist
@Compilerist Жыл бұрын
When generating a new Auth-Token and saving it in the DB, IMO that does change the State. Login and the Pop method on your Example earlier are pretty much the same thing. Right?
@xelaksal6690
@xelaksal6690 Жыл бұрын
As far as I remember Pascal language had basic segregation to procedures(doesn't return value) and functions(returns value)
@joseferreira7415
@joseferreira7415 3 ай бұрын
Should the "Handle" methods in the "RegisterCommand Handler" and "RegisterQueryHandler" classes be asynchronous?
@RochaMarcelo
@RochaMarcelo 2 жыл бұрын
Great video! Will we have a deep dive into the authentication and authorization flow with JWT and OAuth?
@amantinband
@amantinband 2 жыл бұрын
We'll cover it but not sure yet if it will be a deep dive as part of this series
@vicheakh
@vicheakh 2 ай бұрын
i’m new to .net in VS code what is your extension for VS code to help you . thanks
@denisivanov4888
@denisivanov4888 Жыл бұрын
We are using CQRS and IMediatR. In cases where a multiple query/commands must reuse same piece of code, is it ok to call another query/command inside query/command handler or the same code should be extracted to a service and injected in the handler?
@nivaldobrasil
@nivaldobrasil Жыл бұрын
Thank you
@sushilb7994
@sushilb7994 2 жыл бұрын
Great video as always. I'm really enjoying the series. Quick question - where should we apply the validation. From your screenshot (at the end of the video) it looks like it should be done in the application. In my opinion we should also validate the request too. Can you please throw some light here ?
@iliyan-kulishev
@iliyan-kulishev 2 жыл бұрын
Yes, in the application - in the handler for the operation to be exact.
@sunefred
@sunefred 2 жыл бұрын
I would put it in the application or domain entities depending on the scope of the validation. Validation is one of the core reasons to have a domain in the first place in clean architecture.
@sushilb7994
@sushilb7994 2 жыл бұрын
@@sunefred I'm new to clean architecture, thanks for clarifying my doubt.
@pyce.
@pyce. 8 ай бұрын
How would you keep the clean architecture and CQRS structure but not load whole aggregates if not needed like you mentioned at the end?
@tiagorodrigues6284
@tiagorodrigues6284 2 жыл бұрын
How easy is to mock the MediatR Send method for unit tests? Im struggling to see the benefits here of using MediatR vs having Interfaces for each CommandHandler and using that. Great series btw! Thanks :)
@amantinband
@amantinband 2 жыл бұрын
Same as any other interface 🤓 If you have an interface for all your command handlers you will have to manually wire it up in the DI setup, or do assembly scanning similar to what MediatR does out of the box
@KubilayBayraktar
@KubilayBayraktar 2 жыл бұрын
That's great and what we have done, but plus that i'd rather to split persistence layer from application layer. So that the logic and db operations would be separated. 👍
@pilotboba
@pilotboba 2 жыл бұрын
It is. Persistence is in the Infrastructure layer, not the application layer. Or perhaps you are seeing something I missed?
@mahmudx
@mahmudx 2 жыл бұрын
Which tool do you use to draw on the screen?
@mylesdavies9476
@mylesdavies9476 2 жыл бұрын
What software do you use to create the system architecture diagrams? Really like the way it looks
@kerimcetinbas6094
@kerimcetinbas6094 8 ай бұрын
i think it just figma; edit: sorry for after 1 year :D
@ayalamac
@ayalamac 2 жыл бұрын
BTW, what tool are you using for the pointer, frames, and arrows? I think it's cool.
@amantinband
@amantinband 2 жыл бұрын
ZoomIt
@jodainemoore8300
@jodainemoore8300 8 ай бұрын
What Tools are you using for it to predict the code? Sometimes time the entire class..
@rezarezash
@rezarezash Жыл бұрын
Any plan to extend the series to make them Microservice with API gateway?
@zergzerg4844
@zergzerg4844 Жыл бұрын
I didn't get your magic tricks when you install Mediator into the Application project and adding Mediator library from Api project. But Api doesn't have installed mediator library. Or the whole job do Git Compiler?
@DanielLaubinger
@DanielLaubinger 2 жыл бұрын
Hey, always waiting for your next video! :) How did you do the replacement in 5:55? -> Answer is the "Vim Emulator" Extension with the command seen at the blue bottom bar And who can there be a base construct in 11:47?
@amantinband
@amantinband 2 жыл бұрын
Yup regarding vim, not sure what you mean in 11:47
@SUDHIRKUMAR-kx7gz
@SUDHIRKUMAR-kx7gz 2 жыл бұрын
Nice Video. Thanks!. Could you please elaborate why we do need to generate the JWT token during registration process ?
@iliyan-kulishev
@iliyan-kulishev 2 жыл бұрын
You don't necessarily need to do it.
@scryptum
@scryptum 2 жыл бұрын
Hello. Which software do you sue to create these arrows and shapes on the screen? Thanks !
@amantinband
@amantinband 2 жыл бұрын
ZoomIt
@shoesxx1
@shoesxx1 Жыл бұрын
Do you have a list of the extensions you use in VsCode? I would love to see if some of them are available in VS as they look super useful!
@amantinband
@amantinband Жыл бұрын
Yeah I have a video all about vscode for .NET: kzbin.info/www/bejne/o2qrp6Z4ZpKbd9E
@user-sg4kw8uh3m
@user-sg4kw8uh3m Жыл бұрын
Awesome
@alexanderm8169
@alexanderm8169 Жыл бұрын
I've been thinking lately about Azure functions vs web apis. Cost of Azure functions are pretty low comparing to web apis (up to a certain volume of triggers/queues). Web api requires an app service which has an uptime up to 93 - 98%% according to azure datacenters. If its cheaper and you can easy achieve seperation of concerns? Does anyone one know why and when you want to choose the one over the other?
@MinhTran-qn5xd
@MinhTran-qn5xd 2 жыл бұрын
CQRS said that you need to separate Command and Query to database, but in the Register you still need to Query to check user email exists or not. Can you explain is it right when apply CQRS or not
@srezas3580
@srezas3580 Жыл бұрын
I'm really fascinated by the shortcuts that you're using! Is it really the art of vs code extensions and keymaps or you've just cut the video??
@zakustolondoo
@zakustolondoo 2 жыл бұрын
@Amichai thanks very much for this EXCELLENT Tutorial. Just a little bit too fast moving code around. Maybe I hope you don't mind publishing the source code so that one can read it offline to see what is going on?. Many thanks❤
@dicusardenis922
@dicusardenis922 Жыл бұрын
I have an issue with vscode, I don't seem to have the option to "Change namespace to match folder structure" and it is really annoying. Do you know is there a fix for it ? Btw, great searies I really enjoy it and learn a lot, actualy you have inspired me to switch to vscode 👍
@al-doori2392
@al-doori2392 Жыл бұрын
Thanks for the video and the series. May I ask what tool do you use to create diagram of the application, like in 8:18
@amantinband
@amantinband Жыл бұрын
It's GitHub Co-Pilot :)
@ddruganov
@ddruganov Жыл бұрын
you are creating a new token in the login method; doesnt it make it a command? anyway love your vids, thanks
@floralb5317
@floralb5317 2 жыл бұрын
Hello sir, thank you for this great video again. I have a question regarding layers. I see that you create a LoginRequest class and then map it to a LoginQuery by using constructor. Let's suppose we have an incoming request body with at least 20 properties; how would you handle these in controller actions? By manually mapping the fields or is there anything I am missing? Thank you again!
@iliyan-kulishev
@iliyan-kulishev 2 жыл бұрын
Maybe he should've changed the type of the argument of the Login action method to just LoginQuery and scrapped LoginRequest.
@hero3616
@hero3616 2 жыл бұрын
He is going to use AutoMapper in the future I think he mentioned in the first part. I might be wrong tho.
@sushilb7994
@sushilb7994 2 жыл бұрын
@@hero3616 he is going to use Mapster
@amantinband
@amantinband 2 жыл бұрын
Yup, we'll use Mapster
@enriquelamberto3783
@enriquelamberto3783 Жыл бұрын
Is there any argument against using the LoginQuery as Controller request?
@neutronstar482
@neutronstar482 2 жыл бұрын
Awesome explanation and content. If a part of the code that is defined in a Handler has to be used in another Handler, what should be done? Create a service and encapsulate that functionality so as not to repeat code?
@iliyan-kulishev
@iliyan-kulishev 2 жыл бұрын
Depending on the duplication you encounter that might mean that 1) you got your logical boundaries wrong or 2) you indeed have to extract that functionality to separate service/domain service/domain entity.
@pilotboba
@pilotboba 2 жыл бұрын
It depends. What code? Perhaps you need to create some domain events? Keep the SOLID principles in mind.
@pieceofcode_
@pieceofcode_ Жыл бұрын
Hi I'm getting error at line: in .NET 6 Program.cs file builder.Services.AddMediatR(typeof(Program)); Error: CS1503 Argument 2: cannot convert from 'System.Type' to 'System.Action'
@alirezanet
@alirezanet 2 жыл бұрын
One question Amichai: If we also want to update the user's last login DateTime after each login, our login is still a query or a command? How do you separate these two functionalities?
@amantinband
@amantinband 2 жыл бұрын
It would then be command 👍🏼
@singernooneheard6967
@singernooneheard6967 Жыл бұрын
Isnt the model in API and the command reduandant?
@osman3404
@osman3404 2 жыл бұрын
since we now have aspnet minimal APIs, is MediatR redundant?
@99aabbccddeeff
@99aabbccddeeff 9 ай бұрын
I would say, in many cases, yes. We can easily separate logic using Minimal API and inject into every single endpoint different services. Usually MediatR is used in controllers because the last one can have many dependencies but not every endpoint needs them. MediatR allow us to avoid this situation and get less cohesive code. With Minimal API we can reach the same goal without any overhead and additional code. Some people are used to use MediatR and still use it whenever it is possible. Sometimes they as if they refuse to understand that it does more harm than good.
@TheFeljoy
@TheFeljoy 2 жыл бұрын
Great video again :) I like this ideo of splitting by feature. Would you reintroduce a service class again to handle common functionality between different endpoints? And I haven't really understood what the benefit of splitting the contracts project from the api project is. Can anybody shed some light on that?
@iliyan-kulishev
@iliyan-kulishev 2 жыл бұрын
it's just preference for him I guess. If you are fan of multiple classes in one file, you can put each of these classes from /Contracts in the files where the controllers that use them are defined, so you have everything you need in one file. If one really decides to organize by feature (vertical slices) and not technical concerns (horizontal layers), having everything you need for a feature in one place might be the handiest approach: controller, request, response, handler, validator etc. You can even have the UI that is related to that feature in the same folder :)
@SajjadKhan-BSK
@SajjadKhan-BSK Жыл бұрын
Hi Amichai, while using CQRS pattern, shall we need to create class for every query? for Ex: Domain Entity ( Order ) I need queries like GetCustomerOrders / GetPaidOrders / GetCanceledOrders / GetOrdersPaidByCreditCard and also complex queries using Store Procedures(for KPIS / Reports ) So for every query / Stored procedure, we need to create separate Class ??
@IgorfariasSk8
@IgorfariasSk8 Жыл бұрын
Yes, if you will follow that approach you'll respect the S in SOLID principle.
@devnetconsult4434
@devnetconsult4434 Жыл бұрын
Hello as usual, very nice video, but there something I don't understand. At 9:30 you install MediatR package to the application layer. But just after you use IMediator in a controller (from Api project) how is it possibe? do I missed something. Because in my environment if I want to use a library un a controller, I need to install this library in api project.
@amantinband
@amantinband Жыл бұрын
Thanks. In clean arch, outer layers have a dependency only on inner layers. Since the presentation layer references the application layer then it's available.
@devnetconsult4434
@devnetconsult4434 Жыл бұрын
@@amantinband Ok thanks for the quick answer ;-)
@mightybobka
@mightybobka 9 ай бұрын
Best way to return errors is exceptions!
@bobek8030
@bobek8030 2 жыл бұрын
Do you think that using modular monolith with ddd is good approach?
@amantinband
@amantinband 2 жыл бұрын
From the projects I came across, most became really hard to navigate once the shared "building blocks" become generic to support the various modules. Perhaps for devs who are aligned on the architecture it can be super convenient, but it can definitely add another layer of complexity above a single project similar to the one we are building which already can be tough to onboard. Does that make sense?
@pilotboba
@pilotboba 2 жыл бұрын
Is there a reason you don't use the Query and/or Command as the action parameter? That's pretty common in other templates and examples that uses these patterns.
@amantinband
@amantinband 2 жыл бұрын
Even though it saves the mapping in the controller - Yes, a few reasons: 1. In MS (and I'm sure other companies as well), it's common to publish the contracts project as a NuGet package. Then, clients written in .NET can consume it instead of redefining the same models. It also plays well with versioning, where you would simply consume the new version. 2. Commands/Queries aren't always an exact map of the request. A simple example for this is a PUT endpoint, where the id comes from the route. The command would have both details from the request body and the id from the route. 3. It decouples our use cases from the API definition. Want to change names/add properties to a command or query? No problem 🤓 Does that make sense?
@richardhaughton9633
@richardhaughton9633 2 жыл бұрын
Hi, I love the MediatR but I have a problem with it. We can say that the MediatR handler replace our Services Layer. What happens when a service needs to call another services? Jimmy Bogard discourage calling a Mediatr Request from another Request. what is the solution to this problem? reintroduce a service? Thanks for your help
@TheFeljoy
@TheFeljoy 2 жыл бұрын
I assume that if for example registerCommand & loginRequest both required some common functionality, that you would create something like an authenticationService again and use that in the requestHandler. Just my best guess though.
@richardhaughton9633
@richardhaughton9633 2 жыл бұрын
@@TheFeljoy Yes that's what I thought but we are then back to the god Service class.
@TheFeljoy
@TheFeljoy 2 жыл бұрын
@@richardhaughton9633 Mhh, imo it wouldn't become a 'god' class again because it contains only methods that you need to lift out of any single requestHandler for re-use. Similar to how both requestHandlers use the tokenGenerator.
@richardhaughton9633
@richardhaughton9633 2 жыл бұрын
@@TheFeljoy For example let's say I have a CreateEntityRequestHandler that Handles a CreateEntityRequest. Let's also assume that I have an ImportRequestHandler that handles an ImportRequest. When the ImportRequest detects a new Entity it needs to create it. Should I call the CreateEntityRequest and Send it through the MediatR from the ImportRequestHandler?
@geojthachankary8505
@geojthachankary8505 2 жыл бұрын
@@richardhaughton9633 No. You could create a new class, say a repository class that handles the creation of entities in the system.. now you can just inject that class to your CreateEntityHandler and ImportHandler classes so that you could reuse the logic in multiple handlers..
@orewa4019
@orewa4019 2 жыл бұрын
what software that you use in the video, to spawn box and arrow?
@amantinband
@amantinband 2 жыл бұрын
ZoomIt
@orewa4019
@orewa4019 2 жыл бұрын
@@amantinband okay thank you very much, I like to watch your tutorial video
@bilal-elmursi
@bilal-elmursi 2 жыл бұрын
So far, I don't know which is the best case to use the cqrs pattern or the repository pattern.
@pilotboba
@pilotboba 2 жыл бұрын
You can use both. The handlers can use your repository interfaces that are implemented in your infra layer. So, it's not an either/or, they are sort of different concerns.
@bilal-elmursi
@bilal-elmursi 2 жыл бұрын
@@pilotboba Thank You!
@ultragames1915
@ultragames1915 Жыл бұрын
I think it is a stretch, calling a "Login" method a query. Depending on your underlying implementation, it MIGHT write to the persistence store. Ie, if you're not using bearer tokens, but actually storing the login i a database. The name Login, is imperative form, and suggests it is a command, regardless of the underlying implementation. IMO "login" _does_ change state not matter what - maybe not in the database, but conceptually the systems state is changed when invoked, since the user is logged in (which he wasnt before), and that to me, is the definition of a state-change (hence its a command) - not nessecarily a write to a persistence store, since that might change over time and is an infrastructure concern, not application concern
@TheAzerue
@TheAzerue 10 ай бұрын
What benefit we get of duplicating a request and then same props in command or query. Why can't we just use command or query directly as param to Api. ?. This will save some boilerplate code. like LoginRequest and LoginQuery will have same props according to this video.
@martinp3839
@martinp3839 Жыл бұрын
One suggestion. Add a link in your repos to the youtube videos.
@amantinband
@amantinband Жыл бұрын
That's a good idea. I hope to get around to it :)
@ibrahimozturk6147
@ibrahimozturk6147 Жыл бұрын
Follow him with playback speed 0.75😊
@vagnerpadilha3485
@vagnerpadilha3485 2 жыл бұрын
Congratulations on the article Amichai. Let me ask you a question. You don't think using mediatr for the query stack is creating overengineering. Since one of the ideas of CQRS is also to speed up and simplify queries, by using all mediatR objects we are not creating unnecessary objects and instantiating classes that also have a cost. And classes without arguments is quite common, it's just being used to orchestrate to the right handler. Shouldn't we just go straight to the data source? sometimes I get the idea that we create a lot of unnecessary objects for queries.
@hemanthaugust7217
@hemanthaugust7217 2 жыл бұрын
great tutorial, but due to such elaborate classes and structures, people hate java/c# and are preferring much simple golang, which also provides better GC than java.
@ahmedabuelnour1648
@ahmedabuelnour1648 2 жыл бұрын
ErrorOr I wish you can share its code
@amantinband
@amantinband 2 жыл бұрын
I just happen to have a video about it 😉 kzbin.info/www/bejne/qoubmHqnntaSf7c
@Imploser
@Imploser 2 жыл бұрын
People understand mediator as a CQRS pattern, i totally disagree with that. ISender interface wraps Command pattern and it is not about CQRS. It is about request handling per use case,(clean architecture stuff..) IPublisher interface is for in-memory message handling. Normally CQRS is about persistence layer. But, for domain centric projects(you can use DDD) sometimes you need different components for handling that. Every state change on domain could raise a domain event. For that reason, we can use CQRS. It could feed other domains or own query db with that. Also, i think login is a special case and it is not a query. It can generate(also needs HttpPost) a token for that given user. Normally, it is not changing any data on persistence layer but you could persist some columns like last_login_date or device info when business needs. When you login a user, you keep him/her in play. So, user with role is in play for a limited time. When you refresh this token, you gave extra time for that user. For jwt, we don't persist to db, it is in memory. But, also that token contains changed user states which is an authentication result.
@amantinband
@amantinband 2 жыл бұрын
Perhaps I could have been clearer regarding the different patterns we used. I've summed up the details the pinned message 🙂 Regarding login being a command or query, I agree it can definitely be a command as well. I prefer defining flows as queries if they don't change any state, but like everything, it depends on the implementation and person taste. What do you think?
@kennedydre8074
@kennedydre8074 7 ай бұрын
Thank you so much for the videos, I love them, however, it fails to highlight one key aspect which is, you failed to make us beginners understand what problem the MediatR nuget package is trying to solve or why we should even use it. I think explaining the problem the package solves would help us appreciate it and know when to use it and even come up with other impelementations. Again, thank you for your videos and I love them.
@misha130
@misha130 2 жыл бұрын
Wait did I get click baited on Twitter? Where is the controversy
@amantinband
@amantinband 2 жыл бұрын
👀
@ZeroInfinityVideo
@ZeroInfinityVideo Ай бұрын
I don't understand. What happened to old-fashioned Interface extraction of the data for the ViewModel Why am I adding a stupid library for extra download for no good reason? You can create a ViewModel Folder and each entity, create a folder for itself, and create the interface for it. CQRS, something, Create a folder under the same repository and call one of them Transactions or whatever you want to call it to make it clear, and the other one Query. let your services call it accordingly. Make it clear. You don't need all these things and make your code bigger and bigger by adding unnecessary libraries.
@ZeroInfinityVideo
@ZeroInfinityVideo Ай бұрын
And, you don't need any mapping software as well. What is going on? Why are we adding these libraries where you can do it yourselves easily and your project size will be smaller? Are we trying to accommodate not-so-good programmers? Is that why we are having too many hacks?
@maxpuissant2
@maxpuissant2 2 жыл бұрын
This one is not useful in my use case, we build too small API that I prefer the god class than using Mediator.
@ayalamac
@ayalamac 2 жыл бұрын
This goes so fast that it's annoying. Indeed, you know how to do it well, but please go slower, especially on the shortcuts, the contextual menus, and the change of files. You'll become a great YT teacher. Good work!
@amantinband
@amantinband 2 жыл бұрын
I'll keep this in mind for the future videos, thanks for the feedback. I'm thinking of specifying the difficulty level in the beginning of the video so viewers can adjust the playback speed accordingly.
@zikkrype
@zikkrype 2 жыл бұрын
This is rather CQS, not CQRS. All you did just separated classes.
@amantinband
@amantinband 2 жыл бұрын
1:45, 2:27 😉
@cicerofoscarini8890
@cicerofoscarini8890 Жыл бұрын
I really appreciate your videos and the way you explain everything, but... I'm struggling to finish your videos when that "yeeeeessssss" is repeated all the time.
@VOXindie
@VOXindie 3 ай бұрын
MediatR sucks. So does AutoMapper. Don't use them.
@micha8469
@micha8469 2 жыл бұрын
Cool. I have been working with CQRS and MediatR a lot and it's hella clean and works very well with FluentValidation, other/custom middlewares, integration tests and in general with DDD. I've been only wondering why would you register MediatR (or before, without MediatR, your services) in a separate DependencyInjection class and call it in Startup.cs/Program.cs instead of just calling AddMediatR() directly in Program.cs/Startup.cs? Your API layer needs to reference Application, anyway, so what's the point? To keep Application dependencies setup code in Application layer? Wouldn't it be cleaner to create a private method in Program.cs/Startup.cs directly e.g. RegisterApplicationDependencies(serviceCollection) and keep all the setup in one place? I've already seen people going the extension class way and then registering the same thing twice in two different classes, in two different ways, once in Startup.cs directly then in an extension method again because they couldn't keep track on where everything is registered when it's so split, especially developers who didn't write that particular piece of code. What's the gain here?
Жыл бұрын
In .Net Core 7 with version 12 of MediatR on file BuberDinner.Application.DepencyInjection: services.AddMediatR(x => x.RegisterServicesFromAssemblies(typeof(DependencyInjection).Assembly));
@neon2633
@neon2633 10 ай бұрын
Thank you!
How slow is MediatR really?
15:51
Nick Chapsas
Рет қаралды 60 М.
🤔Какой Орган самый длинный ? #shorts
00:42
Дарю Самокат Скейтеру !
00:42
Vlad Samokatchik
Рет қаралды 7 МЛН
That's how money comes into our family
00:14
Mamasoboliha
Рет қаралды 11 МЛН
Is a REST API with CQRS Possible?
16:46
CodeOpinion
Рет қаралды 35 М.
Getting Started with Dapper in .NET
11:29
Amichai Mantinband
Рет қаралды 7 М.
Discovering The Truth About CQRS - No MediatR Required
13:01
Milan Jovanović
Рет қаралды 17 М.
Stop Calling Your API a "REST API"
17:42
Amichai Mantinband
Рет қаралды 15 М.
Don't throw exceptions in C#. Do this instead
18:13
Nick Chapsas
Рет қаралды 253 М.
Clean Architecture vs Domain-Driven Design (DDD) - Understand the Difference
11:26
“.NET 9 Is Killing MediatR, MassTransit & Wolverine!”
11:59
Nick Chapsas
Рет қаралды 81 М.
АЙФОН 20 С ФУНКЦИЕЙ ВИДЕНИЯ ОГНЯ
0:59
КиноХост
Рет қаралды 656 М.
СТРАШНЫЙ ВИРУС НА МАКБУК
0:39
Кринжовый чел
Рет қаралды 1,1 МЛН
iPhone socket cleaning #Fixit
0:30
Tamar DB (mt)
Рет қаралды 12 МЛН
Мой инст: denkiselef. Как забрать телефон через экран.
0:54