Get the source code for this video for FREE → the-dotnet-weekly.ck.page/cqrs-v2 Want to master Clean Architecture? Go here: bit.ly/3PupkOJ Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt
@mrwalkan Жыл бұрын
3:03 isn't repository the one who uses EF?
@nahiandev21 күн бұрын
I was doing CQRS with MediatR, but didn’t get the underlying magic well. This video made me understand how MediatR works under the hood. Nice conceptual explanation! ❤❤
@MilanJovanovicTech20 күн бұрын
Thanks, glad it was helpful!
@sniperharshgaming30478 ай бұрын
Thank you so much. I just started learning about CQRS Pattern and your clean code helped me a lot.
@MilanJovanovicTech8 ай бұрын
Glad to help!
@kasunjalitha2300 Жыл бұрын
Thanks for the great content! I have a suggestion. Could you please make a video about deciding aggregate root. The way you think and the logic you apply in such a scenario. Simply how do you decide? I saw your previous video regarding this. But it would be great if you can explain the decision making part more than coding part in this case. Thanks Milan 😊
@MilanJovanovicTech Жыл бұрын
Great suggestion!
@mitar1283 Жыл бұрын
Ma svaka ti cast milane super Video stvarno si dobro objasnio💪🏻💯. Greetings from germany🇩🇪
@MilanJovanovicTech Жыл бұрын
Hvala, drago mi je da ti se dopala tema! 😁
@2u1u Жыл бұрын
@milan is there anywhere I can see the full implementation of your result class. I think it's such a clean way of writing and resulting results. I'd like to do the same in both personal and professional projects.
Thanks for the video (the guy who asked about domain services…). So is it “ok”/valid to inject the domain service class directly in a handler? Why can’t you create an interface for the domain service (follower service)? Just curious about best practices in ddd using domain services.
@MilanJovanovicTech Жыл бұрын
Why would I need an interface for everything? 😁
@LeotrimJusufi Жыл бұрын
@@MilanJovanovicTech Cuz we are c#-developers 😜 JK. Was just curious on how to implement a domain service. Thank you for the video.
@vupham-i2v Жыл бұрын
thanks for the video, and I think that mentioning db read and write(db recaplication) in this topic is redundant, because CQRS is not related to it, and your example also did not mention anything about db recaplication, in fact you have no cqrs between your application and db (most of time we don't need it because efcore support unit of work), you only have it between your api and application. CQRS is about using different models for read and write, not about db recaplication, even you have db recaplication in your project, you don't need CQRS becausse thoses read and write db are still using the same model (entity)
@Paul-uo9sv Жыл бұрын
Wow
@MilanJovanovicTech Жыл бұрын
Did you even listen to the first 4 minutes?
@Paul-uo9sv Жыл бұрын
@@MilanJovanovicTech yeah exactly
@vupham-i2v Жыл бұрын
@@MilanJovanovicTech yes, I listened to it, but it still redundant, when you mention it first, people will probally misunderstand that what you said is the primary definition, but it is not, you are influential person, what you said will probally lead people to misunderstanding
@vupham-i2v Жыл бұрын
@@MilanJovanovicTech and you did not mention the real definition of CQRS, many people will get it wrong
@BirhanNega Жыл бұрын
That's awesome, Thank you Milan. See you in tommorow morning's @newsletter
@MilanJovanovicTech Жыл бұрын
What did you think of the newsletter?
@SzymonCierzniak Жыл бұрын
I have a minor problem. I setup messaging layer (Command, CommandHandler, Query, QueryHandler) like you, but in what way can I register my handlers within web API? MediatR needs implements IRequest and IRequestHandler, but you didn't implement that
@MilanJovanovicTech Жыл бұрын
Yeah, you'd want to slap either: 1) Slap on MediatR and use that 2) Implement your own service registration code :)
@stefainex99ming2 ай бұрын
Hi, quick question 🙋 I wonder if CQRS needs to be separate the service into two standalone service. Or it can be sit within the same service but having two “handlers”? Cause then we don’t need to face the eventually consistent problem
@MilanJovanovicTech2 ай бұрын
You can do logical splitting, like I'm doing here
@misaghn8027 Жыл бұрын
The best content🤩🤩🤩.
@MilanJovanovicTech Жыл бұрын
Glad you enjoyed this one! :)
@rorycawley Жыл бұрын
Thanks. Would you do an Event Sourcing video please?
@MilanJovanovicTech Жыл бұрын
At some point
@oscarjuliangilbernal6630 Жыл бұрын
Hello, thanks for your video, always i have had this question, the business logic in clean architecture go in domain layer? or in application layer, i have seen others videos where the business logic is in the application layer and not in the domain. thanks.
@MilanJovanovicTech Жыл бұрын
You can do both! What I showed here is placing logic in application use cases. Here's a domain service example: kzbin.info/www/bejne/fofEeJinmp6HhqM
@Paul-uo9sv Жыл бұрын
@@MilanJovanovicTechcool
@flobuilds Жыл бұрын
Great video as always and i have a question. Could you make a video about request localization?
@MilanJovanovicTech Жыл бұрын
Maybe
@schoderfactory3 ай бұрын
What you are doing here (I mean the whole screen shown at 17:00) for me looks very much like a chain of command pattern. You have four actions which must be successful one after the other and, if any of them fails, you want to break the chain. What do you say?
@MilanJovanovicTech3 ай бұрын
Kinda, but not really. Just a transaction script.
@dangerosa013 ай бұрын
Thanks a lot. This is the perfection
@MilanJovanovicTech3 ай бұрын
Glad you like it!
@joehomsum Жыл бұрын
I tried using the SQL server transactional replication technique to replicate from my write database to read database, but I found a critical problem, the replicate is not realtime, it delay about 2 seconds. Imagine user submit/update a form and back to grid listing but the new data is not appears. Just wonder what technology that you use for the projection ?
@MilanJovanovicTech Жыл бұрын
Eventual consistency is something you have to embrace when using this
@joehomsum Жыл бұрын
@@MilanJovanovicTech I found many articles and videos about the theory of Eventual consistency, but didn't find any articles on how to implement it. It will be good if you can show me/us how to implement Eventual consistency for the CQRS pattern.
@Metalyga Жыл бұрын
"You want queries to be fast". The idea of cqrs is to separate reads from writes because reads are often overload database and don't mutating state of record. It is useless to implement cqrs in application that are not using read database replicas. If you mutate record all you do is propagating changes to read replicas and you can put load away from write db. Another thing is queries can go through business logic because some processes require validation through process. For e.g. if attendee does not have appointment in certain timeframe he cant get info about other attendee. Does this use case mutate data? No. But it must pass validation business rules. But even in this case you can use cqrs and it will be viable if only you have heavy read load and you have read db replica. So in the end cqrs is not needed with single database and query can pass domain layer.
@MilanJovanovicTech Жыл бұрын
It's far from useless even on single-DB applications
@Metalyga Жыл бұрын
@@MilanJovanovicTech Even Martin Fowler who heavily promotes it says that cqrs is "must be deep down in your toolbag" from goto talk from 2017. And it is like that. cqrs is bringing complexity, produces more garbage to collect, brings needs of separation between what query needs to pass domain layer and what is not, don't give you real benefit in small-medium size apps, because it depends on db and infrastructure. For e.g. cassandra has slower reads than writes. It is tool and it better to use it when its needed. So this is about "You want queries to be fast" and not implementation. Your implementation like many other is good as always 😁.
@Targeting-Must-End Жыл бұрын
Good video. Thank you mam
@MilanJovanovicTech Жыл бұрын
Most welcome 😊
@dmitryye4756 Жыл бұрын
Thank you for the great content, Milan. Have you a git for your examples? Often, while watching the video, linked questions appear. And, imho, it is more useful to look at the code to understand where it is located, referenced, and implemented related things rather than search for them on the video. Thanks
@MilanJovanovicTech Жыл бұрын
I share the code on Patreon: www.patreon.com/milanjovanovic
@rsmetalhead247 ай бұрын
Is it an anti-pattern to call queries inside command handlers ? For example, you want to fetch some entity from the db to update it inside a command handler. It seems like we can avoid duplicating querying logic by using a query inside a command handler instead of injecting repository or raw sql. The query handler will already have an implementation where it calls repository or raw sql.
@MilanJovanovicTech7 ай бұрын
I wouldn't call it an anti-pattern, just a misuse of intent
@sarwalgauravАй бұрын
Is it good idea to create a base command handler which have crores cutting concerns like validation, logging, exception handling etc
@MilanJovanovicTechАй бұрын
Do that with middleware (decorator)
@sarwalgauravАй бұрын
@@MilanJovanovicTech Thanks for replying but on other hand we have pipeline behaviour which can handle all these cross cutting concerns, so I am not sure in which scenarion I will try to force all my command handlers to have base handler when pipeline behaviour can do the same in more flexible way. Can you please share some link or video for middleware decorator. Thanks for caring and sharing the knowledge :)
@ДерзкийДерзкий-т9д6 ай бұрын
How do I understand what should be a domain level service (FollowerService), and what should be an Application Layer Service or Use Case Command Handler? Both have business logic, both use Repositories etc...??? As far as I understood from your previous videos - the main difference between onion architecture and clean architecture is that onion architecture uses services, while clean architecture is about use cases. Anyway. Lets imaging I use onion architecture. I have FollowerService. Should FollowerService be Domain level or Application Layer Service? Or I should have 2 FollowerServices at both places? What kind of logic then should be inside each one?
@MilanJovanovicTech6 ай бұрын
How do you differentiate domain logic and application logic?
@ДерзкийДерзкий-т9д6 ай бұрын
@@MilanJovanovicTech Probably I don't know how to differentiate it, still learning, that's why I keep asking questions:)
@ДерзкийДерзкий-т9д6 ай бұрын
@@MilanJovanovicTech Hmmm, probably my I don't even know how to ask a question correctly due to lack of experience. I should've probably asked - What kind of logic belongs to domain layer (so domain services) and what kind of logic should be placed to application service layer
@jorgetovar1063 Жыл бұрын
Hey Milan can you share what's on sharedkernel project?
@MilanJovanovicTech Жыл бұрын
Here's the video: kzbin.info/www/bejne/hpqxe2V5lqhmedk
@jorgetovar1063 Жыл бұрын
@@MilanJovanovicTech thanks! your content is pure gold for dev community!
@afgone123456 Жыл бұрын
Can I ask which theme or colour do you use for VS?
@MilanJovanovicTech Жыл бұрын
ReSharper syntax highlighting
@HarmenKooiker Жыл бұрын
Is the ICommandHandler inheriting from Mediatr IRequestHandler?
@MilanJovanovicTech Жыл бұрын
Yeah
@HarmenKooiker Жыл бұрын
thanks, i thought so but was not clear in the video@@MilanJovanovicTech
@AnthonyDavies-r1fАй бұрын
Excellent work
@MilanJovanovicTechАй бұрын
Many thanks!
@fadthegreat Жыл бұрын
As always superb content! 👌
@MilanJovanovicTech Жыл бұрын
Glad you think so!
8 ай бұрын
Hi Milan! One question! Why FollowingService (where have the logic) are in Domain Layer?? Should be in Application Layer, no? 🤔
@MilanJovanovicTech8 ай бұрын
I see you found the Domain Service video :)
@simonreiff38899 ай бұрын
Great video! I have a question. Suppose I am using Dapper for the write side as well as the read side while implementing DDD and clean architecture, including the CQRS pattern. I can easily replace a DbContext implementation with my standard class library using Dapper that contains methods for saving and loading data from the database, then call those methods from the repository implementations in the infrastructure layer. It seems like nearly everything else (DDD, CQRS, repositories, etc.) all would remain just as you have it, but does UnitOfWork become extraneous in that scenario as an EF Core-specific item? Or would I still use the UOW even with Dapper on the write side?
@MilanJovanovicTech8 ай бұрын
UoW with Dapper is pretty tough to implement. You'll have to do it yourself. Unless there's a NuGet package I don't know about.
@simonreiff38898 ай бұрын
@@MilanJovanovicTech Thanks so much for responding so quickly! Typically, I push transactions into stored procedures written in SQL that I can trigger through a custom 'SaveData' method using Dapper (with generic arguments for the stored procedure and parameters). After thinking very carefully about your setup, I think I'm not going to need UoW with Dapper, given my approach of pushing transactions to the database level and requiring the database either to accept or reject all changes in a single transaction. I just put a method in my repository, say 'UpdateLineItem', which uses the SaveData method using Dapper calling, say, 'UpdateLineItem.sql' and whatever parameters, and then performs all transactions internally inside of the database. The only scenario I can foresee possibly needing a UoW pattern given my setup would be if, for some reason, I ever need to write a transaction that affects multiple databases where I must roll back everything if anything fails. Am I missing another reason to use the UoW pattern if I handle transactions entirely at the SQL level? Thanks again for your help!!
@MahmoudSaed985 ай бұрын
why did you put FollowerService class in Domain Layer not in Application Layer ?
@MilanJovanovicTech5 ай бұрын
I consider it a domain service: kzbin.info/www/bejne/fofEeJinmp6HhqM
@marcelotieghi936 Жыл бұрын
Nice video! I have two questions for you. In the video, you mentioned using Dapper for queries. Now, with EF8 SqlQuery, which one do you think is best to use: SqlQuery or Dapper? Another question is, how do you set up the 'Add => New From Template' option?
@MilanJovanovicTech Жыл бұрын
2) ReSharper 1) You can use both. EF 8 raw SQL queries aren't as performant and the mapping is cumbersome
@LeotrimJusufi Жыл бұрын
Hi again! Another question: If u call on another entity in the domain service; does that become an application service? Or can you still call another domain in another domain service?
@MilanJovanovicTech Жыл бұрын
At that point I'd say it depends where you place the service
@jz4887 Жыл бұрын
Why you create UserRepository and UnitOfWork in application layer instead of domain layer? Explain pls
@MilanJovanovicTech Жыл бұрын
It's just an interface definition, has no dependencies, and only uses Domain entities
@jz4887 Жыл бұрын
@@MilanJovanovicTech Thank u for answer. In other words we don't care where the repository interfaces are declared? I thought it was important.
@ДерзкийДерзкий-т9д6 ай бұрын
Why is IUserRepository defined at the Application Services level? How do you make a choice where should be the Repository interface - inside domain level, like IFollowerRepository, or inside Application Level like IUserRepository?
@MilanJovanovicTech6 ай бұрын
Isn't the repository at domain level? (That's where I usually place it). I use repositories only for domain entities, so I place them in domain. I don't use them for ad-hoc queries or returning DTOs.
@ДерзкийДерзкий-т9д6 ай бұрын
@@MilanJovanovicTech I can see that you define IUserRepository at the same file with StartFollowingCommandHandler. Do I miss something in the video? Isn't StartFollowingCommandHandler - application service layer?
@Amplified12511 ай бұрын
Could we please get your Visual Studio font related color configuration? I love it :) Puno pozdrava iz Hrvatske i hvala na fenomenalnom sadržaju :)
@MilanJovanovicTech11 ай бұрын
Font je default "dark theme" za Visual Studio + ReSharper syntax highlighting. Nisam siguran da mogu da exportujem ovo kao temu.
@arteqppp6223 Жыл бұрын
Great video as always. What benefit do repository gives us? Just the ability to switch to different ORM without changing logic inside of our handlers? Is it worth it extra time and complexity? I dont imagine for now to implement repositories inside of my full time job project. I just staight code ef core on dbcontext inside of handler, which I guess saves me a lot of time and effort. Is there any extra benefit of using repository? Also, Im really surprised by holding all the business logic inside of Domain project. Is there something wrong with doing everything inside of handler? I also sometimes do some "ApplicationLayerService" class just to share same logic between two handlers. I need to learn more of domain Services from Your videos, because I think that might be more elegant way of code than my current way of writing it. Thanks Milan!
@MilanJovanovicTech Жыл бұрын
- Encapsulation (of queries) - Code reuse (no duplication) - Cross-cutting concerns (transactions, caching, logging) - Most importantly (for me): TESTABILITY I only use repositories on write (command side) because I want to test this. If you see value in this, then great.
@arteqppp6223 Жыл бұрын
@@MilanJovanovicTech Thank You for sharing Your valuable knowledge Milan!
@andreibicu559210 ай бұрын
@@MilanJovanovicTech I find myself asking the same questions as @arteqppp6223. The principles you enumerated should be a priority for every developer. 1. With the shift to minimal apis, CQRS, we are now more focused on the features, rather than technical layers. I like it more and it makes more sense. Don't you think we could extend this to repositories too? Why not have commands and queries at the repository level? 2. It's not very clear for me when we should introduce a domain service. Should it only when we have a shared logic between handlers? Also, it's very uncommon to see a call to the repository in a domain model. Do you have some references to better explain the domain services ? Thanks!
@akashkarve19919 ай бұрын
How do you sync your read database with write database?
@MilanJovanovicTech9 ай бұрын
kzbin.info/www/bejne/aIuxfp-uaZmagbM
@Omarahmed-fs8jv10 ай бұрын
Hi Milan, appreciate your video and insights! Wondering if implementing CQRS is beneficial for optimizing response times in a rating system, especially when dealing with large amounts of data, to prevent incorrect reads or potential deadlocks? Thanks!
@MilanJovanovicTech10 ай бұрын
It could be
@_NguyenHaoTien3 ай бұрын
That's insightful, but I have a question about the Principles of CQRS. Should each request inject one IMediator or more? Because if I inject IMediator in another Handler, it may break the principle. It's really hard while writing a test.
@MilanJovanovicTech3 ай бұрын
I'd say just once
@kodindoyannick53282 ай бұрын
Thanks for this video! I like It.
@MilanJovanovicTech2 ай бұрын
I'm glad you like it
@mahdi9145 ай бұрын
Why are you using Repositories in the Domain? Isn't supposed to be used in Application Services only?
@MilanJovanovicTech5 ай бұрын
kzbin.info/www/bejne/qHiTamOYarKFfdE
@mrinaltantubai734110 ай бұрын
Do you have any udemy course? On microservices and all CQRS ????
@MilanJovanovicTech10 ай бұрын
I have one on Clean Architecture + CQRS + DDD - www.milanjovanovic.tech/pragmatic-clean-architecture
@lmora0011 ай бұрын
How call the command and queries from controllers?
@MilanJovanovicTech11 ай бұрын
new ComandHandler().Handle(command)
@NavneetKumar-fs2mc Жыл бұрын
Thank you Milan for high quality content. I have two questions, need your help to understand Mediator and CQRS pattern. 1. About CQRS - It is good idea to use this pattern if you want to use 2 databases, one for write and another one for read operations. My questions are : 1. There is high chance of delay in data sync bwt write to read database, how to deal with it? 2. If I want to use single database for both read and write, Is it worth using this pattern? 3. If I want to fetch data based on multiple filters rather getbyId or getbyemail. Is this fine? and how to achieve it? 4. How to handle if I have to fetch data from multiple tables in one go..
@MilanJovanovicTech Жыл бұрын
1. a) Wait until the sync completes - b) Accept that you'll be eventually consistent and work around it 2. Yes 3. As you would with any complex query 4. Multiple split queries, or joins
@GrishmaDoshi Жыл бұрын
Thank you for sharing your knowledge. After watching this video I have 2 questions: 1)In my project generally we follow this: Create generic repo, if needed extend repo for specific class. And then use those repo withing Services layer and call them on controller. But here I see you used commands and queries which are relying on Services. Instead can't we have simply 2 set of services for read and write? (My question might not be the best but I am just trying to understand what is with to add another layer of calls) 2)Let say once I get clarity on my 1st question then is it good practice to call repository and services both on handler or is better only use services on command and no direct access to repository? TIA @MillanJovanovicTech
@MilanJovanovicTech Жыл бұрын
1) Commands/Queries are what you do in the Services, pretty much. Your service method becomes a Command/Query class. 2) Yes, it's fine to use repositories/services from handlers
@lmora0011 ай бұрын
this a way to implement CQRS Pattern without MediatR?
@MilanJovanovicTech11 ай бұрын
Nope, this will end up using MediatR later
@SianDelaCruz-r4q Жыл бұрын
Why are there repositories? Why not access dbcontext directly to the handler?
@hugokane1943 Жыл бұрын
Because in this pattern, you're trying to segregate domain and data logic. This is opinionated, and as such, isn't strictly required. But, if you wanted to change the database implementation, directly applying dbcontext into a handler would mean that its tightly coupled with the database implementation which isn't always ideal.
@MilanJovanovicTech Жыл бұрын
To encapsulate EF queries, reduce code duplication, improve testability
@SianDelaCruz-r4q Жыл бұрын
should I Rewrite my code and use repository pattern?
@sunzhang-d9v Жыл бұрын
@@SianDelaCruz-r4q
@jishnuchandran34146 ай бұрын
I am just learning CQRS using your videos, and I have a few doubts. Could you please help me to solve, I have a request for calculating some operations in a database. It involves a few insertions and updates. After the operation, I get List of some data. In CQRS, how should I handle this scenario? Should I put this logic on the command side or the query side? and one more thing Can we use a common DTO in the CQRS pattern?
@MilanJovanovicTech6 ай бұрын
I would suggest also reading about CQRS, from some books or article, instead of just watching YT videos 😁
@dieg0dgm Жыл бұрын
What about the presenters?
@MilanJovanovicTech Жыл бұрын
I don't explicitly define them
@dieg0dgm Жыл бұрын
@@MilanJovanovicTech Couldn't they be used to construct the use case response instead of returning value?
@hugokane1943 Жыл бұрын
Is there a reason why the command handler can't directly implement the service logic? Curious what the reasoning behind this is.
@MilanJovanovicTech Жыл бұрын
It can. It's about where you want the logic to be - domain or application layers. Which further impacts testability and how you want to test the logic.
@hugokane1943 Жыл бұрын
Thanks for the reply Milan. You've always got the best videos on this stuff!@@MilanJovanovicTech
@PhucHuynh-xp4fh Жыл бұрын
Could u give me an example for using HttpContext in Handler? Recently, I research for this problem but I can not find out the expected result. Some of them I think I will pass it from Controller or DI HttpContextAccesstor into Handler, it's right for this design patern?
@iamorhanmir Жыл бұрын
builder.Services.AddSingleton(); Try this and inject in handler hopefully it will work fine.
@pilotboba Жыл бұрын
I personally like to separate the external implementations from the use cases. So, rather than getting or using the context in the handler, add the items you need from the HTTP context into the command. Since the API/Presentation layer creates the command, it has access to the context. Although, yes it is possible to inject ContextAccessor into your handler.
@MilanJovanovicTech Жыл бұрын
You would end up using IHttpContextAccessor. A better approach would be to abstract this behind a service that will use the HttpContext. That implementation can be in Infra.
@abbassiziad13799 ай бұрын
Thanks for sharing and your great explanation. But, It still a hard concept to implement.
@MilanJovanovicTech9 ай бұрын
Conceptually, it really isn't... The practical implementation can be as simple or as complex as you like.
@buildingphase97129 ай бұрын
The problem with this implementation is that you would have to manually maintain those sql query strings when the domain properties change, l think EF is still a great option for huge projects.
@MilanJovanovicTech9 ай бұрын
I'm fine with that
@oneside5418 Жыл бұрын
OP 🤩
@MilanJovanovicTech Жыл бұрын
Thanks a lot! :)
@daniel-peiro Жыл бұрын
MediatR at application is not Clean Architecture
@MilanJovanovicTech Жыл бұрын
Ok
@onelastkiwi80412 ай бұрын
wow
@MilanJovanovicTech2 ай бұрын
😱
@shimadabr4 ай бұрын
This video made me remember how bloated C# is with language constructs lol
@MilanJovanovicTech4 ай бұрын
sorry to trigger the ptsd
@АлексейДемин-ъ5ж Жыл бұрын
а можно без медиатор, плжалуйста. это же ужасно.
@MilanJovanovicTech Жыл бұрын
Da
@madd5 Жыл бұрын
Stop scaring people with that stare lol
@MilanJovanovicTech Жыл бұрын
Hey, I have to live with that stare... You think that's easy? 😂
@madd5 Жыл бұрын
@@MilanJovanovicTech lol
@pilotboba Жыл бұрын
As Nathan says on Upload. "It's just my face". So, it's just his face. :)