Тёмный
No video :(

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

Amichai Mantinband
Подписаться 50 тыс.
Просмотров 66 тыс.
50% 1

Опубликовано:

 

21 авг 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 156   
@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 RU-vid.... Keep it up....
@efimov90
@efimov90 2 года назад
12:56 isn't it better to return ValueTask.FromResult() if it is async now?
@necatiakpnar5519
@necatiakpnar5519 14 дней назад
I've watched many many people online but you are foremost the best one!
@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 5 месяцев назад
Thank you!
@ramjaane47
@ramjaane47 9 дней назад
Thanks!
@emilzyka6853
@emilzyka6853 Год назад
Hands down best explanation of CQRS I have found with non-trivial practical example to understand how it is implemented. Thank you!
@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)
@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.
@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 😊
@TrOgaN_
@TrOgaN_ 2 месяца назад
I'm following this course using .Net 8, so far so good. This was an enlightening section, thanks for putting it together.
@Hassanlou
@Hassanlou Год назад
There's no doubt that the series is great, but the comments and answers are also valuable as I learn from them.
@silvertek
@silvertek 2 года назад
I need more! This series is fantastic, cant get episodes fast enough :D
@TayyabMughalDIK
@TayyabMughalDIK 2 года назад
I am already loving this series
@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😅
@MilanJovanovicTech
@MilanJovanovicTech 2 года назад
This is the way! 🛣🛣🛣
@TiagoPereira-rf9jf
@TiagoPereira-rf9jf 2 года назад
Another amazing video, can't wait for the next one :D
@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!
@willhunt3000
@willhunt3000 Год назад
Amichal - great video as usual. Great, concise and comprehensible info.
@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
@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 👀
@xelaksal6690
@xelaksal6690 Год назад
As far as I remember Pascal language had basic segregation to procedures(doesn't return value) and functions(returns value)
@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!
@nthonymiller
@nthonymiller Год назад
Thanks, this how I've been implementing my apps. So much clearer to reason about the code base.
@homerreal
@homerreal 2 года назад
Love your videos
@afsanehhazeghi8890
@afsanehhazeghi8890 2 года назад
Good job as always. I can`t wait for your upcoming videos.
@HaysBays-gd2lf
@HaysBays-gd2lf 10 месяцев назад
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 RU-vid. I hope to talk about Dockers and containers. Thanks again.
@DanielTames
@DanielTames 2 года назад
I really appreciate your content man! than you very much!
@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?
@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.
@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?
@tawhidurrahman2780
@tawhidurrahman2780 Год назад
please make videos on testing, CI/CD. your explanations are awesome 👍❤
@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
@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
@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❤
@hirusalempuri3907
@hirusalempuri3907 2 года назад
I am in love with your content, wait for the next videos eagerly, when are u coming up with next videos?
@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?
@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
@rezarezash
@rezarezash Год назад
Amazing video - Many thanks
@mightybobka
@mightybobka 10 месяцев назад
Best way to return errors is exceptions!
@pyce.
@pyce. 10 месяцев назад
How would you keep the clean architecture and CQRS structure but not load whole aggregates if not needed like you mentioned at the end?
@vipuldimri6571
@vipuldimri6571 2 года назад
Great Video
@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
@osman3404
@osman3404 2 года назад
since we now have aspnet minimal APIs, is MediatR redundant?
@99aabbccddeeff
@99aabbccddeeff 10 месяцев назад
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.
@nivaldobrasil
@nivaldobrasil Год назад
Thank you
@ibrahimozturk6147
@ibrahimozturk6147 Год назад
Follow him with playback speed 0.75😊
@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??
@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?
@pasindushalinda7979
@pasindushalinda7979 2 года назад
Awesome tutorial ♥️
@kvojps-yt
@kvojps-yt 4 месяца назад
Should the "Handle" methods in the "RegisterCommand Handler" and "RegisterQueryHandler" classes be asynchronous?
@ddruganov
@ddruganov Год назад
you are creating a new token in the login method; doesnt it make it a command? anyway love your vids, thanks
@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?
@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?
@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
@scryptum
@scryptum 2 года назад
Hello. Which software do you sue to create these arrows and shapes on the screen? Thanks !
@amantinband
@amantinband 2 года назад
ZoomIt
@user-sg4kw8uh3m
@user-sg4kw8uh3m Год назад
Awesome
@rezarezash
@rezarezash Год назад
Any plan to extend the series to make them Microservice with API gateway?
@jodainemoore8300
@jodainemoore8300 9 месяцев назад
What Tools are you using for it to predict the code? Sometimes time the entire class..
@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'
@TheAzerue
@TheAzerue 11 месяцев назад
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.
@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.
@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?
@vicheakh
@vicheakh 3 месяца назад
i’m new to .net in VS code what is your extension for VS code to help you . thanks
@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!
@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 :)
@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 :)
@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?
@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?
@mylesdavies9476
@mylesdavies9476 2 года назад
What software do you use to create the system architecture diagrams? Really like the way it looks
@kerimcetinbas6094
@kerimcetinbas6094 9 месяцев назад
i think it just figma; edit: sorry for after 1 year :D
@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
@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..
@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?
@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.
@singernooneheard6967
@singernooneheard6967 Год назад
Isnt the model in API and the command reduandant?
@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?
@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 👍
@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.
@ayalamac
@ayalamac 2 года назад
BTW, what tool are you using for the pointer, frames, and arrows? I think it's cool.
@amantinband
@amantinband 2 года назад
ZoomIt
@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.
@mahmudx
@mahmudx 2 года назад
Which tool do you use to draw on the screen?
Год назад
In .Net Core 7 with version 12 of MediatR on file BuberDinner.Application.DepencyInjection: services.AddMediatR(x => x.RegisterServicesFromAssemblies(typeof(DependencyInjection).Assembly));
@neon2633
@neon2633 11 месяцев назад
Thank you!
@shoesxx1
@shoesxx1 2 года назад
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: ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-m9HvsB1-hAo.html
@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 👍🏼
@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.
@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 :)
@ZeroInfinityVideo
@ZeroInfinityVideo 2 месяца назад
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.
@kennedydre8074
@kennedydre8074 8 месяцев назад
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.
@devnetconsult4434
@devnetconsult4434 2 года назад
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 2 года назад
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 2 года назад
@@amantinband Ok thanks for the quick answer ;-)
@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?
@ZeroInfinityVideo
@ZeroInfinityVideo 2 месяца назад
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?
@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
@ahmedabuelnour1648
@ahmedabuelnour1648 2 года назад
ErrorOr I wish you can share its code
@amantinband
@amantinband 2 года назад
I just happen to have a video about it 😉 ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-tZ8gGqiq_IU.html
@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.
@misha130
@misha130 2 года назад
Wait did I get click baited on Twitter? Where is the controversy
@amantinband
@amantinband 2 года назад
👀
@robertmills8101
@robertmills8101 24 дня назад
Why are you separating command and query outside of IAuthenticationService? No code outside of the implementation cares. You're introducing something and a LOT of code that doesn't matter. The implementation of authentication's repository (maybe IAuthenticationRepository) might care because there is a read side and a write/transaction side, but not at the front end or what should be a very thin, single line, of code in the controller. Oh, and what happens if login requires a counter update to restrict failures every n minutes? Also, even query commands will/might update the log database, but I guess that doesn't count. Sorry for the rant.
@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.
@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.
@zikkrype
@zikkrype 2 года назад
This is rather CQS, not CQRS. All you did just separated classes.
@amantinband
@amantinband 2 года назад
1:45, 2:27 😉
@VOXindie
@VOXindie 4 месяца назад
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?
Далее
Don't throw exceptions in C#. Do this instead
18:13
Просмотров 256 тыс.
Новый фонарик в iPhone с iOS 18
00:49
Просмотров 487 тыс.
Stop Calling Your API a "REST API"
17:42
Просмотров 16 тыс.
Intro to MediatR - Implementing CQRS and Mediator Patterns
1:21:50
Clean ASP.NET Core API using MediatR and CQRS | Setup
22:39
Getting Started with Dapper in .NET
11:29
Просмотров 11 тыс.
The Best Way To Organize Your Program.cs In ASP.NET
6:59