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

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

Amichai Mantinband

2 года назад

65,353 Просмотров

Ссылки и html тэги не поддерживаются


Комментарии:

@amantinband
@amantinband - 14.07.2022 15:20

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 🙂

Ответить
@kennedydre8074
@kennedydre8074 - 16.12.2023 05:12

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.

Ответить
@jodainemoore8300
@jodainemoore8300 - 19.11.2023 05:14

What Tools are you using for it to predict the code? Sometimes time the entire class..

Ответить
@pyce.
@pyce. - 25.10.2023 12:42

How would you keep the clean architecture and CQRS structure but not load whole aggregates if not needed like you mentioned at the end?

Ответить
@mightybobka
@mightybobka - 01.10.2023 12:22

Best way to return errors is exceptions!

Ответить
@TheAzerue
@TheAzerue - 14.09.2023 23:19

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.

Ответить
@Hassanlou
@Hassanlou - 12.08.2023 08:52

There's no doubt that the series is great, but the comments and answers are also valuable as I learn from them.

Ответить
@emilzyka6853
@emilzyka6853 - 02.08.2023 15:12

Hands down best explanation of CQRS I have found with non-trivial practical example to understand how it is implemented. Thank you!

Ответить
@tawhidurrahman2780
@tawhidurrahman2780 - 16.07.2023 16:35

please make videos on testing, CI/CD. your explanations are awesome 👍❤

Ответить
@FabioMattes
@FabioMattes - 02.06.2023 20:33

In .Net Core 7 with version 12 of MediatR on file BuberDinner.Application.DepencyInjection:

services.AddMediatR(x => x.RegisterServicesFromAssemblies(typeof(DependencyInjection).Assembly));

Ответить
@user-wb1ip7be6u
@user-wb1ip7be6u - 08.05.2023 00:13

Update on how you should implement the DI in Mediatr starting version 12.0.0:

services.AddMediatR(config => config.RegisterServicesFromAssembly(typeof(DependencyInjection).Assembly));

Ответить
@ddruganov
@ddruganov - 06.05.2023 18:37

you are creating a new token in the login method; doesnt it make it a command?
anyway love your vids, thanks

Ответить
@philiphendry8008
@philiphendry8008 - 23.04.2023 10:52

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?

Ответить
@denisivanov4888
@denisivanov4888 - 05.04.2023 12:04

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?

Ответить
@ibrahimozturk6147
@ibrahimozturk6147 - 04.04.2023 01:00

Follow him with playback speed 0.75😊

Ответить
@pieceofcode_
@pieceofcode_ - 01.03.2023 14:45

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<Microsoft.Extensions.DependencyInjection.MediatRServiceConfiguration>'

Ответить
@ultragames1915
@ultragames1915 - 27.02.2023 10:29

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

Ответить
@SajjadKhan-BSK
@SajjadKhan-BSK - 31.01.2023 14:05

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 ??

Ответить
@dicusardenis922
@dicusardenis922 - 03.01.2023 09:39

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 👍

Ответить
@singernooneheard6967
@singernooneheard6967 - 30.12.2022 16:02

Isnt the model in API and the command reduandant?

Ответить
@nthonymiller
@nthonymiller - 30.12.2022 14:58

Thanks, this how I've been implementing my apps. So much clearer to reason about the code base.

Ответить
@user-sg4kw8uh3m
@user-sg4kw8uh3m - 27.12.2022 14:58

Awesome

Ответить
@rezarezash
@rezarezash - 15.12.2022 08:09

Any plan to extend the series to make them Microservice with API gateway?

Ответить
@rezarezash
@rezarezash - 15.12.2022 08:08

Amazing video - Many thanks

Ответить
@xelaksal6690
@xelaksal6690 - 12.12.2022 13:26

As far as I remember Pascal language had basic segregation to procedures(doesn't return value) and functions(returns value)

Ответить
@Compilerist
@Compilerist - 07.12.2022 01:47

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?

Ответить
@willhunt3000
@willhunt3000 - 05.12.2022 16:40

Amichal - great video as usual. Great, concise and comprehensible info.

Ответить
@srezas3580
@srezas3580 - 30.10.2022 15:06

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??

Ответить
@alexanderm8169
@alexanderm8169 - 27.10.2022 23:41

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?

Ответить
@zergzerg4844
@zergzerg4844 - 03.10.2022 16:44

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?

Ответить
@cicerofoscarini8890
@cicerofoscarini8890 - 17.09.2022 19:29

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.

Ответить
@nivaldobrasil
@nivaldobrasil - 17.09.2022 18:54

Thank you

Ответить
@gremlinx7819
@gremlinx7819 - 03.09.2022 13:47

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?

Ответить
@shoesxx1
@shoesxx1 - 01.09.2022 23:45

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!

Ответить
@DemoBytom
@DemoBytom - 25.07.2022 15:21

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.

Ответить
@hirusalempuri3907
@hirusalempuri3907 - 24.07.2022 06:03

I am in love with your content, wait for the next videos eagerly, when are u coming up with next videos?

Ответить
@homerreal
@homerreal - 23.07.2022 21:48

Love your videos <3 Can't wait to see the rest of the series.

Ответить
@wvanlosser
@wvanlosser - 21.07.2022 12:15

Just found this series this week. Very interesting and informative. Much thanks for creating this series and keep up the good work!

Ответить
@mylesdavies9476
@mylesdavies9476 - 19.07.2022 17:52

What software do you use to create the system architecture diagrams? Really like the way it looks

Ответить
@MinhTran-qn5xd
@MinhTran-qn5xd - 18.07.2022 08:52

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

Ответить
@hemanthaugust7217
@hemanthaugust7217 - 17.07.2022 09:18

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.

Ответить
@micha8469
@micha8469 - 16.07.2022 22:27

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?

Ответить
@mahmudx
@mahmudx - 16.07.2022 20:35

Which tool do you use to draw on the screen?

Ответить
@vagnerpadilha3485
@vagnerpadilha3485 - 16.07.2022 10:47

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.

Ответить
@APARTtolondoo
@APARTtolondoo - 15.07.2022 12:10

@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❤

Ответить