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
@mrwalkan11 ай бұрын
3:03 isn't repository the one who uses EF?
@kasunjalitha230011 ай бұрын
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 😊
@MilanJovanovicTech11 ай бұрын
Great suggestion!
@stefainex99ming14 күн бұрын
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
@MilanJovanovicTech14 күн бұрын
You can do logical splitting, like I'm doing here
@sniperharshgaming30475 ай бұрын
Thank you so much. I just started learning about CQRS Pattern and your clean code helped me a lot.
@MilanJovanovicTech5 ай бұрын
Glad to help!
@LeotrimJusufi11 ай бұрын
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.
@MilanJovanovicTech11 ай бұрын
Why would I need an interface for everything? 😁
@LeotrimJusufi11 ай бұрын
@@MilanJovanovicTech Cuz we are c#-developers 😜 JK. Was just curious on how to implement a domain service. Thank you for the video.
@NavneetKumar-fs2mc10 ай бұрын
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..
@MilanJovanovicTech10 ай бұрын
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
@ДерзкийДерзкий-т9д3 ай бұрын
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?
@MilanJovanovicTech3 ай бұрын
How do you differentiate domain logic and application logic?
@ДерзкийДерзкий-т9д3 ай бұрын
@@MilanJovanovicTech Probably I don't know how to differentiate it, still learning, that's why I keep asking questions:)
@ДерзкийДерзкий-т9д3 ай бұрын
@@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
@vupham-i2v11 ай бұрын
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-uo9sv11 ай бұрын
Wow
@MilanJovanovicTech11 ай бұрын
Did you even listen to the first 4 minutes?
@Paul-uo9sv11 ай бұрын
@@MilanJovanovicTech yeah exactly
@vupham-i2v11 ай бұрын
@@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-i2v11 ай бұрын
@@MilanJovanovicTech and you did not mention the real definition of CQRS, many people will get it wrong
@2u1u11 ай бұрын
@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.
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.
@MilanJovanovicTech11 ай бұрын
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-uo9sv11 ай бұрын
@@MilanJovanovicTechcool
@marcelotieghi93611 ай бұрын
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?
@MilanJovanovicTech11 ай бұрын
2) ReSharper 1) You can use both. EF 8 raw SQL queries aren't as performant and the mapping is cumbersome
@LordErnie11 ай бұрын
A premium quality video. Well done indeed.
@MilanJovanovicTech11 ай бұрын
Thanks, glad you enjoyed this one :)
@BirhanNega11 ай бұрын
That's awesome, Thank you Milan. See you in tommorow morning's @newsletter
@MilanJovanovicTech11 ай бұрын
What did you think of the newsletter?
@Omarahmed-fs8jv8 ай бұрын
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!
@MilanJovanovicTech8 ай бұрын
It could be
@LeotrimJusufi11 ай бұрын
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?
@MilanJovanovicTech11 ай бұрын
At that point I'd say it depends where you place the service
@_NguyenHaoTienАй бұрын
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.
@MilanJovanovicTechАй бұрын
I'd say just once
@dmitryye475610 ай бұрын
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
@MilanJovanovicTech10 ай бұрын
I share the code on Patreon: www.patreon.com/milanjovanovic
@schoderfactoryАй бұрын
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?
@MilanJovanovicTechАй бұрын
Kinda, but not really. Just a transaction script.
@mitar128311 ай бұрын
Ma svaka ti cast milane super Video stvarno si dobro objasnio💪🏻💯. Greetings from germany🇩🇪
@MilanJovanovicTech11 ай бұрын
Hvala, drago mi je da ti se dopala tema! 😁
@arteqppp622311 ай бұрын
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!
@MilanJovanovicTech11 ай бұрын
- 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.
@arteqppp622311 ай бұрын
@@MilanJovanovicTech Thank You for sharing Your valuable knowledge Milan!
@andreibicu55928 ай бұрын
@@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!
@simonreiff38896 ай бұрын
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?
@MilanJovanovicTech6 ай бұрын
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.
@simonreiff38896 ай бұрын
@@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!!
@GrishmaDoshi11 ай бұрын
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
@MilanJovanovicTech11 ай бұрын
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
@rsmetalhead244 ай бұрын
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.
@MilanJovanovicTech4 ай бұрын
I wouldn't call it an anti-pattern, just a misuse of intent
6 ай бұрын
Hi Milan! One question! Why FollowingService (where have the logic) are in Domain Layer?? Should be in Application Layer, no? 🤔
@MilanJovanovicTech6 ай бұрын
I see you found the Domain Service video :)
@jishnuchandran34144 ай бұрын
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?
@MilanJovanovicTech4 ай бұрын
I would suggest also reading about CQRS, from some books or article, instead of just watching YT videos 😁
@flobuilds11 ай бұрын
Great video as always and i have a question. Could you make a video about request localization?
@MilanJovanovicTech11 ай бұрын
Maybe
@Metalyga11 ай бұрын
"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.
@MilanJovanovicTech11 ай бұрын
It's far from useless even on single-DB applications
@Metalyga11 ай бұрын
@@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 😁.
@rorycawley11 ай бұрын
Thanks. Would you do an Event Sourcing video please?
@MilanJovanovicTech11 ай бұрын
At some point
@SzymonCierzniak10 ай бұрын
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
@MilanJovanovicTech10 ай бұрын
Yeah, you'd want to slap either: 1) Slap on MediatR and use that 2) Implement your own service registration code :)
@ДерзкийДерзкий-т9д3 ай бұрын
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?
@MilanJovanovicTech3 ай бұрын
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д3 ай бұрын
@@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?
@CarlosMay-t8h2 ай бұрын
A million thanks! you are the best!
@MilanJovanovicTechАй бұрын
Glad it helped!
@mrinaltantubai73418 ай бұрын
Do you have any udemy course? On microservices and all CQRS ????
@MilanJovanovicTech8 ай бұрын
I have one on Clean Architecture + CQRS + DDD - www.milanjovanovic.tech/pragmatic-clean-architecture
@Amplified1259 ай бұрын
Could we please get your Visual Studio font related color configuration? I love it :) Puno pozdrava iz Hrvatske i hvala na fenomenalnom sadržaju :)
@MilanJovanovicTech9 ай бұрын
Font je default "dark theme" za Visual Studio + ReSharper syntax highlighting. Nisam siguran da mogu da exportujem ovo kao temu.
@afgone12345611 ай бұрын
Can I ask which theme or colour do you use for VS?
@MilanJovanovicTech11 ай бұрын
ReSharper syntax highlighting
@HarmenKooiker11 ай бұрын
Is the ICommandHandler inheriting from Mediatr IRequestHandler?
@MilanJovanovicTech11 ай бұрын
Yeah
@HarmenKooiker11 ай бұрын
thanks, i thought so but was not clear in the video@@MilanJovanovicTech
@joehomsum11 ай бұрын
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 ?
@MilanJovanovicTech11 ай бұрын
Eventual consistency is something you have to embrace when using this
@joehomsum11 ай бұрын
@@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.
@dangerosa01Ай бұрын
Thanks a lot. This is the perfection
@MilanJovanovicTechАй бұрын
Glad you like it!
@MahmoudSaed982 ай бұрын
why did you put FollowerService class in Domain Layer not in Application Layer ?
@MilanJovanovicTech2 ай бұрын
I consider it a domain service: kzbin.info/www/bejne/fofEeJinmp6HhqM
@buildingphase97127 ай бұрын
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.
@MilanJovanovicTech7 ай бұрын
I'm fine with that
@jorgetovar10639 ай бұрын
Hey Milan can you share what's on sharedkernel project?
@MilanJovanovicTech9 ай бұрын
Here's the video: kzbin.info/www/bejne/hpqxe2V5lqhmedk
@jorgetovar10639 ай бұрын
@@MilanJovanovicTech thanks! your content is pure gold for dev community!
@jz488711 ай бұрын
Why you create UserRepository and UnitOfWork in application layer instead of domain layer? Explain pls
@MilanJovanovicTech11 ай бұрын
It's just an interface definition, has no dependencies, and only uses Domain entities
@jz488711 ай бұрын
@@MilanJovanovicTech Thank u for answer. In other words we don't care where the repository interfaces are declared? I thought it was important.
@lmora009 ай бұрын
this a way to implement CQRS Pattern without MediatR?
@MilanJovanovicTech9 ай бұрын
Nope, this will end up using MediatR later
@mahdi9143 ай бұрын
Why are you using Repositories in the Domain? Isn't supposed to be used in Application Services only?
@MilanJovanovicTech3 ай бұрын
kzbin.info/www/bejne/qHiTamOYarKFfdE
@PhucHuynh-xp4fh11 ай бұрын
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?
@iamorhanmir11 ай бұрын
builder.Services.AddSingleton(); Try this and inject in handler hopefully it will work fine.
@pilotboba11 ай бұрын
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.
@MilanJovanovicTech11 ай бұрын
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.
@misaghn802711 ай бұрын
The best content🤩🤩🤩.
@MilanJovanovicTech11 ай бұрын
Glad you enjoyed this one! :)
@abbassiziad13797 ай бұрын
Thanks for sharing and your great explanation. But, It still a hard concept to implement.
@MilanJovanovicTech7 ай бұрын
Conceptually, it really isn't... The practical implementation can be as simple or as complex as you like.
@hugokane194311 ай бұрын
Is there a reason why the command handler can't directly implement the service logic? Curious what the reasoning behind this is.
@MilanJovanovicTech11 ай бұрын
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.
@hugokane194311 ай бұрын
Thanks for the reply Milan. You've always got the best videos on this stuff!@@MilanJovanovicTech
@fadthegreat11 ай бұрын
As always superb content! 👌
@MilanJovanovicTech11 ай бұрын
Glad you think so!
@Targeting-Must-End11 ай бұрын
Good video. Thank you mam
@MilanJovanovicTech11 ай бұрын
Most welcome 😊
@akashkarve19917 ай бұрын
How do you sync your read database with write database?
@MilanJovanovicTech7 ай бұрын
kzbin.info/www/bejne/aIuxfp-uaZmagbM
@lmora009 ай бұрын
How call the command and queries from controllers?
@MilanJovanovicTech9 ай бұрын
new ComandHandler().Handle(command)
@dieg0dgm11 ай бұрын
What about the presenters?
@MilanJovanovicTech11 ай бұрын
I don't explicitly define them
@dieg0dgm11 ай бұрын
@@MilanJovanovicTech Couldn't they be used to construct the use case response instead of returning value?
@SianDelaCruz-r4q11 ай бұрын
Why are there repositories? Why not access dbcontext directly to the handler?
@hugokane194311 ай бұрын
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.
@MilanJovanovicTech11 ай бұрын
To encapsulate EF queries, reduce code duplication, improve testability
@SianDelaCruz-r4q11 ай бұрын
should I Rewrite my code and use repository pattern?
@sunzhang-d9v11 ай бұрын
@@SianDelaCruz-r4q
@oneside541811 ай бұрын
OP 🤩
@MilanJovanovicTech11 ай бұрын
Thanks a lot! :)
@daniel-peiro11 ай бұрын
MediatR at application is not Clean Architecture
@MilanJovanovicTech11 ай бұрын
Ok
@shimadabr2 ай бұрын
This video made me remember how bloated C# is with language constructs lol
@MilanJovanovicTech2 ай бұрын
sorry to trigger the ptsd
@onelastkiwi804117 күн бұрын
wow
@MilanJovanovicTech17 күн бұрын
😱
@АлексейДемин-ъ5ж10 ай бұрын
а можно без медиатор, плжалуйста. это же ужасно.
@MilanJovanovicTech10 ай бұрын
Da
@techpc545310 ай бұрын
@MilanJovanovicTech10 ай бұрын
👋
@madd511 ай бұрын
Stop scaring people with that stare lol
@MilanJovanovicTech11 ай бұрын
Hey, I have to live with that stare... You think that's easy? 😂
@madd511 ай бұрын
@@MilanJovanovicTech lol
@pilotboba11 ай бұрын
As Nathan says on Upload. "It's just my face". So, it's just his face. :)