Implementing Modular Architecture With Sync Communication

  Рет қаралды 9,811

Milan Jovanović

Milan Jovanović

Күн бұрын

Пікірлер: 53
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
Want to master Clean Architecture? Go here: bit.ly/3PupkOJ Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt
@developmentroselino
@developmentroselino 2 ай бұрын
another day saved by milan, thank you so much for the lesson. its so much cleaner but im not separating by per project yet.
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Happy to help! :)
@dotnetMasterCSharp
@dotnetMasterCSharp 2 ай бұрын
This is awesome and useful content thank you
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Glad it was helpful!
@Districtgame
@Districtgame 7 ай бұрын
But doesn't that lead to distributed monolith antipattern? If you do it like this you are not able to use training module (in this case of course) without waiting for response of users module and that leads to question if these modules shouldn't be one. This is only easy example but in real world there will be a lot of references like this and if you need response from others modules to be able to finish your request there is maybe no point in separating these modules. Anyway, thank you for your videos they are awesome!
@EducateReality
@EducateReality 7 ай бұрын
yes, but I suggest you to get more in touch with the domain you are in and also the word „useage“ also a lot times used as „user“. I think your case is a useage case (where a user is useing a module). This useage is a specific module! I assume your next question, but don’t forget to set boundaries!
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
This does make sense. Which is why all decisions should be made in a given context. Keep in mind that the example in the video is contrived, to illustrate an idea/concept.
@lucasi-cs
@lucasi-cs 7 ай бұрын
Where would you put common classes that are used in all modules? For instance, a custom pagination class
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
Create a Common/Shared project that all modules can reference
@iagosoriano3734
@iagosoriano3734 7 ай бұрын
What would the dependency injection look like in the Training module? If the implementation of the UsersApi lives inside the Users.Infrastructure project, how would you inject it into the Training application, since the Training module only know the Users.Api project? Shouldn't only the interface to the Users public Api live in the Users module and its implementation in the common Infrastructure project?
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
DI takes care of it at runtime.
@iagosoriano3734
@iagosoriano3734 7 ай бұрын
@@MilanJovanovicTech In that case, you'd need a single DI container for all modules, and would have to avoid name conflicts among dependencies in different modules, right? I'm implementing a modular monolith in Node, and went with this one-container-per-module route.
@ahmedrizk106
@ahmedrizk106 7 ай бұрын
what I do instead is to use Request/Response pattern provided by Mass Transit to avoid any coupling between the two modules, I have a contracts nuget package which is shared between all my modules/microservices, any module/microservices can simply request the data without any module knowing anything about where the response is coming from exactly. what do you think about this solution ?
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
They're still coupled by the nature of request-response, though. Just wrote about it: www.milanjovanovic.tech/blog/request-response-messaging-pattern-with-masstransit
@ChristopherBriddock
@ChristopherBriddock 7 ай бұрын
Milan, you should put out a code tip. To resolve your dependencies from the DI container rather than making an instance of the dependency inside a class. Like you have done in your CreateWorkoutCommandHandler. First you would need the IServiceProvider as a property with just a getter, amd initialized in the constructor, then you can use the GetRequiredService method to resolve dependencies from the DI container.
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
Sorry, which dependency is that? 🤔
@slvberg
@slvberg 7 ай бұрын
Thanks for the video! Considering an alternative approach to the coupling: what if we add a Repository interface in the Training module's application to call the Users module API? This could simplify future efforts to split the Users module out of the monolith, without needing to touch the Training module's application logic. Plus, it would only require re-implementing the repository within the Training module, to fetch from the new Users module API, like REST. Just a thought to explore further.
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
That's like an Anti-Corruption Layer. I like the idea, for sure. We can even make it return an Athlete object, instead of a User. It's something I touched on in the MM course. Might cover it in the future videos in this series.
@petewarner1077
@petewarner1077 7 ай бұрын
Why implement IUserApi in the user module infrastructure project? If for example you were using a mediator pattern to dispatch requests to the user API, the handlers(implementations) for those requests naturally live at the application level, not the infrastructure level. We push implementations of non-deterministic code that produces side-effects (e.g IO operations) to the infrastructure, but an API is logically deterministic. Therefore I'd argue it should be implemented at the application level.
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
It makes more sense to me to implement this as part of Infrastructure, since it's an implementation of an abstraction. If it were a interface defined at the Application layer, where would you place the implementation?
@RobertoGarcia-w7y
@RobertoGarcia-w7y 3 ай бұрын
@@MilanJovanovicTech The strategy is fine, is really semantic. Let's suppose that you've an interface called UserFetcher then on your infrastructure layer you'd have a HttpUserFetcher or a QueryBusUserFetcher or whatever doesn't matters, in the end it's what it's, an implementation detail on the infrastructure layer. Nice job, thanks for the video
@VintunaSayami
@VintunaSayami 7 ай бұрын
1. I didn't understood the concept of creating separate class library for same module. In User module, why do we need to create new class library for each section. Infrastructure, Domain, Api. Is it okey if we segregate it from folder only?? 2. You have created the shared Infrastructure which is again created in User module. what is the purpose of Shared Infrastructure??
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
1. It's just Clean Architecture. You can use anything. 2. Shared Infra is for cross-cutting stuff. Module Infra is for Users module only.
@mahmadmusffir8459
@mahmadmusffir8459 7 ай бұрын
Please create a tutorial on how to implement logging in SignalR for measuring and improving the performance of Hub methods.
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
Will consider
@sunzhang-d9v
@sunzhang-d9v 7 ай бұрын
Each module is given a different database, what if you need to federate the query, and the amount of data is very large
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
Merge the modules if the query is frequent. Or live with the added latency if it's not so frequent. We can also explore data duplication. Many options here
@ASIMKHAN-ig9eo
@ASIMKHAN-ig9eo 7 ай бұрын
Can we do this with shadow properties?
@sunzhang-d9v
@sunzhang-d9v 7 ай бұрын
@@ASIMKHAN-ig9eo how to do it
@sunzhang-d9v
@sunzhang-d9v 7 ай бұрын
@@MilanJovanovicTech data duplication?
@ASIMKHAN-ig9eo
@ASIMKHAN-ig9eo 7 ай бұрын
i am also curious to know as i also need some content on this as this is a problem
@stephendgreen1502
@stephendgreen1502 7 ай бұрын
They should have taught us all this decades ago. Well done.
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
I believe we were. What I want to know is how it became lost.
@stephendgreen1502
@stephendgreen1502 7 ай бұрын
@@MilanJovanovicTech Lack of proper engineering approach. Poor training in universities. Recruiters focussing on irrelevant skills. Immature developers being promoted and fast-tracked before they acquired proper understanding.
@nove1398
@nove1398 7 ай бұрын
Great gems here, a pretty debated topic online now.
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
As with any fad. Let's see how long it lasts.
@joga_bonito_aro
@joga_bonito_aro 7 ай бұрын
While I understand why some scenarios would require a modular monolith, I wouldn't go out of my way and create a module for every aggregate root entity. You would introduce one very big side effect, which would force you to track the distributed database consistency manually via manual atomicity handling/tracking. And doing such for every entity... just DON'T do it!
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
I agree. Maybe I should preface the videos with "this is a contrived" example?
@joga_bonito_aro
@joga_bonito_aro 7 ай бұрын
@@MilanJovanovicTech To me, the side effects seem like a no-brainer, but only after years of hurt, shitty programming and trial and error. Newcomers on the other hand wouldn't necessarily know the pros and cons right away. A preamble with pros and cons would suffice IMHO.
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
@@joga_bonito_aro That's a great point. As I'm planning a batch of videos right now. Keeping that in mind. Few slides at the start might be a good idea.
@joga_bonito_aro
@joga_bonito_aro 7 ай бұрын
@@MilanJovanovicTech Almost forgot. Great video as always Milan.
@TheScriptPunk
@TheScriptPunk 7 ай бұрын
sir, lean into it. You know you want to... @satyayuga0 How about, a pattern where data is validated in, and falls into a pipeline. The pipeline is where the actual modularity takes place. The edge services can be distributed, or, confined within the same process. The consuming services shift their role from calling down to a direct reference of a handler, to a message bus (which is what you were doing before, except instead of explicitly typed parameters, you get to play with either grpc data, or json. I guess). Then, operate on the message bus. The requesting api customer will wait until all broad downstream effects bubble up, as you'd expect (expect your pieces probably have latent activity more than direct method calls) But, if you do this, you gain the benefit of not having to stick your service on 1 host process.
@icewolf1911
@icewolf1911 7 ай бұрын
Excellent video!
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
Ty!
@phw1009
@phw1009 7 ай бұрын
Such a nice approach, but copying Errors for user to Training module looks a bit smelly. I believe there is a better approach for that
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
Temporary solution mostly.
@YehorBachurinDev
@YehorBachurinDev 7 ай бұрын
1️⃣
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
Speedy!
Data isolation for Modular Monoliths - DB Schemas, EF Core
16:02
Milan Jovanović
Рет қаралды 9 М.
The Beginner's Guide to Clean Architecture
13:19
Milan Jovanović
Рет қаралды 33 М.
黑天使被操控了#short #angel #clown
00:40
Super Beauty team
Рет қаралды 61 МЛН
Гениальное изобретение из обычного стаканчика!
00:31
Лютая физика | Олимпиадная физика
Рет қаралды 4,8 МЛН
It’s all not real
00:15
V.A. show / Магика
Рет қаралды 20 МЛН
Keep your project structure simple!
15:08
CodeOpinion
Рет қаралды 19 М.
Getting Started with Modular Monoliths in .NET
12:37
Milan Jovanović
Рет қаралды 27 М.
Real 10x Programmers Are SLOW To Write Code
14:51
Thriving Technologist
Рет қаралды 68 М.
Event-Driven Architecture (EDA) vs Request/Response (RR)
12:00
Confluent
Рет қаралды 177 М.
Onion Architecture vs Clean Architecture Comparison
13:44
Milan Jovanović
Рет қаралды 47 М.
The Fix For Your Database Performance Issues in .NET
9:12
Nick Chapsas
Рет қаралды 84 М.
Inside a Futuristic Home with Detachable Rooms | Unique Spaces | Architectural Digest
12:08
Tired of Layers? Vertical Slice Architecture to the rescue!
12:26
Domain-Driven Design: The Last Explanation You'll Ever Need
21:05
Software Developer Diaries
Рет қаралды 14 М.
黑天使被操控了#short #angel #clown
00:40
Super Beauty team
Рет қаралды 61 МЛН