Getting Started with Modular Monoliths in .NET

  Рет қаралды 19,025

Milan Jovanović

Milan Jovanović

Күн бұрын

☄️ Master the Modular Monolith Architecture: bit.ly/3SXlzSt
📌 Accelerate your Clean Architecture skills: bit.ly/3PupkOJ
🚀 Support me on Patreon to access the source code: / milanjovanovic
A modular monolith is a catchy name for a monolith system built from a few bounded contexts (modules) and following a set of principles to control coupling. Each module contains a cohesive set of functionalities and is isolated from other modules in the system. The isolation refers to database dependencies and inter-module communication. In this video, I'll explain the fundamentals of this architectural approach. You will also see a practical Modular Monolith implementation in .NET.
Check out my courses: bit.ly/3PupkOJ
What Is a Modular Monolith?
www.milanjovanovic.tech/blog/...
Monolith to Microservices: How a Modular Monolith Helps
www.milanjovanovic.tech/blog/...
Monolith to Microservices: How a Modular Monolith Helps:
www.milanjovanovic.tech/blog/...
Join my weekly .NET newsletter:
www.milanjovanovic.tech
Read my Blog here:
www.milanjovanovic.tech/blog
Chapters
0:00 What is a Modular Monolith?
1:28 Some architecture diagrams
3:45 Modular Monolith diagram
4:46 How to build a Modular Monolith
5:47 Module communication
8:11 Module data isolation
10:19 Demo: Modular Monolith in .NET

Пікірлер: 115
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
💡You can learn more about Modular Monolith Architecture here: bit.ly/3SXlzSt
@davidpccode
@davidpccode 2 ай бұрын
I took you CleanArchitecture course....it's the most clear and consise i've ever seen. Thank you Millan you are such a nice and professional person. Thank you very much
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Wow, thank you! This course should be a very nice extension, but much more advanced.
@theincredibleillmo9385
@theincredibleillmo9385 2 ай бұрын
Waiting for this course no matter what the clowns and haters say. Much love and mad respect from 🇲🇽 Mexico we! ❤❤❤
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Apprecaite it, and returning the love back! 😁
@user-rx2jr2nb8r
@user-rx2jr2nb8r 2 ай бұрын
Thank you for sharing this excellent video! It's clear, concise, and well done. Keep up the great work!
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Glad it was helpful!
@thiagomatu
@thiagomatu 2 ай бұрын
Looking forward for this next course Milan
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
About a ~month out from now, lots of work ahead
@qamislo9740
@qamislo9740 2 ай бұрын
​@@MilanJovanovicTech Please hurry up with the course😊😊
@dcuccia
@dcuccia 2 ай бұрын
Should be a great course based on all the content presented so far. Looking forward to it.
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Hope so! Starting work on it today 🤞😁
@TechnicalVibs
@TechnicalVibs 2 ай бұрын
wonderfully explained in a short way
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Glad you liked it!
@saddamhossaindotnet
@saddamhossaindotnet 2 ай бұрын
Great video, my friend 🧡
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Thank you 🤗
@datadigger2432
@datadigger2432 2 ай бұрын
You are the best of the best and do not listen to silly comments Keep going ❤️❤️
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Had to set the record straight 😁
@datadigger2432
@datadigger2432 2 ай бұрын
Great video milan thanks
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Glad you enjoyed it :)
@supremedev4851
@supremedev4851 2 ай бұрын
Great video. Thanks 👍
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Thank you very much! :)
@EugeneZavalko
@EugeneZavalko 2 ай бұрын
Great explanation
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Glad you liked it
@umeshyeware1409
@umeshyeware1409 2 ай бұрын
Hi Milan, this is really cool implementation. Always love watching your videos. Just one help if you can explain how you are implementing InstallModule and InstallServices method with help of assembly loading in detail in your future video or shorts, it would be great help.
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
I talked about the general idea here: kzbin.info/www/bejne/qnyod2mulsqin8k You can see the IServiceInstaller concept. The IModuleInstaller is the same thing, just implemented for each module.
@umeshyeware1409
@umeshyeware1409 2 ай бұрын
@@MilanJovanovicTech Thank you for quick reply
@Kasiux
@Kasiux 2 ай бұрын
Milan, the best .NET/Tech KZbinr
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Thanks a lot, glad you think so 😁
@pedrosilva1437
@pedrosilva1437 2 ай бұрын
This is good introduction to modular monoliths and interested in seeing more content about this. However, I'm not sure about the added complexity of using a message broker. It makes the modular monolith more complicated, and seems to only be beneficial if you're hedging you bets on moving to microservices later.
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Yes, I agree there's a tradeoff to be made here
@marklnz
@marklnz Ай бұрын
Thanks for the concise explanation. I'm even more convinced now that modular monoliths have no real use case, unfortunately. But thanks for confirming that!
@MilanJovanovicTech
@MilanJovanovicTech Ай бұрын
Dumbest take ever 😂
@marklnz
@marklnz Ай бұрын
@@MilanJovanovicTech You're entitled to your opinion, but I'm sticking to mine - modular monoliths are nonsense. Either break it up or stick with it, don't bother half-assing it, it's only going to make everyone's life a misery if you do.
@raycarlbrown-amory3509
@raycarlbrown-amory3509 2 ай бұрын
fantastic video
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Thanks a lot! :)
@yaminnather521
@yaminnather521 2 ай бұрын
How do you do dependency injection for classes that are the same in both the modules? For example, I have an Outbox class defined in a project that two modules share. But since you can't register two objects of the same type in Dependency Injection, i have to create wrapper classes for each modules, like ModuleAOutbox and ModuleBOutbox
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
They may have the same name, but if the namespaces is different it's not the same type. It's actually something I will touch on in a future video, where I will implement the Outbox pattern like that.
@yaminnather521
@yaminnather521 2 ай бұрын
​@@MilanJovanovicTech That's true, but I'm sharing using an Outbox from a common package so I don't have to implement it per package, I can't register an Outbox per module since the namespace will be the same right? Is what I'm doing already the only way(creating wrappers per module)? It's very annoying do it like that lol. And there's another thing I'm confused about if you could spare some time, do you build all objects and their Dependencies in the Composition Root? I was considering another alternative since the Composition Root was getting too messy. Is using Inversion of Control and then constructing the object using a Factory which provides all the non dynamic parameters, and dynamic parameters as parameters in the build fuction, a nice approach? In the Composition Root I would then mostly pick the implementations I need for the abstractions. This way the smaller stuff like, for example, Mappers(for mapping between Domain and Database Mpdel) of a Repository dont' have to be added in the Composition Root, making it less cluttered imo. Any advice that you can give on these. Sorry for making you read this big block of text if you did read it and thanks :)
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
@@yaminnather521 I usually implement an extension method that configures DI per module. And then register all the modules from the composition root. The reason for this is decoupling the modules, so I can easily pull out one module and move it into a separate application. Does that make sense? It's quite common to duplicate stuff between modules, if you want to make them decoupled and independent.
@AkosLukacs42
@AkosLukacs42 2 ай бұрын
​@@yaminnather521if you are calling the exact same DI registration code from two places, most likely you could just replace AddXY calls with TryAddXy, and should work, since the latter won't register it second time. Of course this only applies if the dependency registration is the same.
@yaminnather521
@yaminnather521 2 ай бұрын
@@MilanJovanovicTech Yeah that makes sense. Thanks.
@alexandrehando
@alexandrehando 2 ай бұрын
Excellent video! We are migrating our legacy application exactly in this context, how would you suggest to implement/adapt some high coupling entities, such as User, in new features or legacy features that are being migrated? Thanks!
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Coupled stuff goes together, check my longer videos on Modular Monoliths.
@HomeSlize
@HomeSlize Ай бұрын
Thanks for the content! I'm interested in your Modular Monolith course but can you share some details on the extra 2 hours of video content and the extra 7 lessons in the MMA + Community option? Thanks!
@MilanJovanovicTech
@MilanJovanovicTech Ай бұрын
The 7 lessons are from the bonus course. It's a condensed version of the main one, from a slightly different angle.
@alexandrehando
@alexandrehando Ай бұрын
Hey Milan, how would you suggest doing complex filtering data between modules? Like User has Teams, but in Company (another module) has only team and my filter would be Company that has X teams. Thanks!
@MilanJovanovicTech
@MilanJovanovicTech Ай бұрын
Implement that functionality in a single module?
@user-jk8ii8mt2y
@user-jk8ii8mt2y 2 ай бұрын
At some point is the artificial separations within the modular monolith more harmful than beneficial on the performance side? For instance, let’s say I am making 4 internal api calls to get the data from the necessary modules for a single external call from the ui. At what point should I just scrap it, write a view with a few joins, and get the data in one call to the db?
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
That's a pretty good signal that your module boundaries are probably wrong. You shouldn't have to talk to other modules so much that it impacts your performance negatively. Let's do a thought experiment. If that was a microservices system, what would you do?
@alejomillo7744
@alejomillo7744 2 ай бұрын
The EF Core feature of lazy loading and retrieiving the relations as part of the query is lost if using this modular monolith architecture right? Since from my users module for example I don't have access to the Orders entity neither does the database, right?
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Yes
@grzegorzr3621
@grzegorzr3621 2 ай бұрын
In Different Schema, how to check who placed the order from the orders level if the usernames are in users.*? Can I use users.* tables in the Orders module to take advantage of the advantages of a relational database?
@iamprovidence-xj5wf
@iamprovidence-xj5wf 2 ай бұрын
I guess the same way you would do it with microservices. create users table in orders.* schema or access it through api of users module
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
I'll explain how in a future video. I recommend reading this in the meantime: www.milanjovanovic.tech/blog/modular-monolith-communication-patterns TL;DR 1) Query the Users module to get the data. This should be done through a public API 2) Duplicate the data in both modules somehow
@grzegorzr3621
@grzegorzr3621 2 ай бұрын
ad1 What if I return a list of orders with different users? Should I ask about each one separately? ad2 Duplicate the data: and there is additional work to maintain current data between modules. I'm thinking that I want more information than just username when ordering. E.g. avatar, account creation date, etc. In the case of database queries, this is very simple. Does this separation introduce too much complexity?
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
@@grzegorzr3621 Which of the two would you choose in a microservices system?
@grzegorzr3621
@grzegorzr3621 2 ай бұрын
​@@MilanJovanovicTech I don't know. I don't know about this.
@PinoyDevAko
@PinoyDevAko 2 ай бұрын
Hi Milan. Excited for your upcoming course. One little thing, can kindly find a way to make your "video player" fluid or a bit responsive? I maybe one of those few who finds your video player annoying because it is fixed to a maximum size. I bought other courses and they have quite similar player but their player is not fixed to maximum size.
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
It's a limitation of Teachable (the platform I'm using), so not much I can do about it :/
@PinoyDevAko
@PinoyDevAko 2 ай бұрын
I see@@MilanJovanovicTech . So not an option to change the platform? :) Have you tried watching videos that has a small player and then you have to maximize the whole browser, not allowing you to multi-task or even code-along with you? :) I hope you understand.
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
@@PinoyDevAko Not an option to switch platforms. There is an option to see how I can increase the default size. It's something I'm looking into.
@PinoyDevAko
@PinoyDevAko 2 ай бұрын
Thank you @@MilanJovanovicTech . Again you're wonderful and one of the best out there.
@GuillermoValenzuela-Dev
@GuillermoValenzuela-Dev 26 күн бұрын
Excellent video Milan. One question here, with modular monolith would we lose the possibility of scaling each module according to demand?
@MilanJovanovicTech
@MilanJovanovicTech 26 күн бұрын
You never had the ability for granular scalability with any monolith application. It's all or nothing.
@KingOfBlades27
@KingOfBlades27 2 ай бұрын
When I create Azure function app that uses injected services does that count as modular monolith? Services are registered in start up and then used through interfaces which is a bit different than using api. But idea seems to be pretty much the same 🤔
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
I wouldn't consider that a modular monolith
@nanvlad
@nanvlad 2 ай бұрын
Is message broker running outside of the process of monolith app? Or is it just a logical module to communicate between layers like MediatR?
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
In this case, it's in-process behind a MassTransit abstraction. But because of this, I can just add a RabbitMQ instance, update MassTransit to connect to it, and all else works the same
@marko95g
@marko95g Ай бұрын
hi, I have a question regarding message broker, how one module fetch data from another module? for example, order module requires user data, so it will send a request to message broker, and what should happen next? if I understand this, at the end, order module must wait for user data in order to continue execution, right? so basically, order module will use "sync" way to solve this problem?
@MilanJovanovicTech
@MilanJovanovicTech Ай бұрын
Request-response is sync, however way you look at it. Async would imply processing messages outside of the normal request flow. You'd process a 'UserRegistered' event, and store that info in the other module as a local copy. Then, you can query from the local copy when you need user data.
@marko95g
@marko95g Ай бұрын
@@MilanJovanovicTech this can be very very complex..thanks!
@datadigger2432
@datadigger2432 2 ай бұрын
Can you please milan make a video about using grpc for microservices
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Will do, at some point :)
@cartongessow10
@cartongessow10 2 ай бұрын
what tool did you use for diagrams?
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Excalidraw for the "shiny ones" and draw.io for the C4 diagrams (but you can do C4 diagrams in other tools)
@DanielCipra
@DanielCipra 2 ай бұрын
What is up with the Bind and Tap methods? Is that from some nuget package?
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Sorry 'bout that 😅 I was applying ROP on this project.
@erradil
@erradil 2 ай бұрын
Great thanks. could have access to the demo repository
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
It's shared on Patreon
@bobek8030
@bobek8030 2 ай бұрын
How you separate di containers for modules?
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
You don't necessarily have to. And the built-in DI doesn't support that. You have to use something like Autofac.
@dannym817
@dannym817 2 ай бұрын
Can we see somewhere all code? Like in github?
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
I share all the source code on Patreon, and for some videos you can find it in the description
@phw1009
@phw1009 2 ай бұрын
Master..... I will join the modular side of the force...
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Come to the, erm..., modular side? 😂 lol
@hugobarroca9538
@hugobarroca9538 Ай бұрын
Good explanations and clear graphics! Good work on the video! 🙂
@MilanJovanovicTech
@MilanJovanovicTech Ай бұрын
Thank you! 😃
@Cornet435
@Cornet435 2 ай бұрын
How can one module fetch data from another?
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Read this: www.milanjovanovic.tech/blog/modular-monolith-communication-patterns I'll release a few more videos soon.
@user-xm7sh3vw8o
@user-xm7sh3vw8o 2 ай бұрын
love
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Thanks!
@vincentcifello4435
@vincentcifello4435 2 ай бұрын
The "Tight Coupling" slide depicts interactions within a monolith. These are classes calling each other. The arrows going back and forth show the coupling. Ok, fine. The next slide "Method Calls" shows Modules calling each other with a "clearly defined public interface". This presumably deals with the "Tight Coupling" previously shown. The problem, of course, is that these are exactly the same. Classes are modules, by definition. Classes have a clearly defined public interface. Naming these objects "Modules" does nothing to solve the problem. Presumably, the modules are calling each other in order to get data that is "isolated" (or not) in the other module so that the calling module can make some decision and perform an action. That means that the boundaries are incorrect and the modules are not really modules because they are not autonomous- ie they can not make independent decisions and can not be changed in isolation. I would also point out that temporal decoupling, while important from a performance and systems view, doesn't really decouple anything. If you are using events to propagate data between these modules, then that is still tight coupling. It is just asynchronous. Temporal coupling can not exist unless there is an actual form of coupling that underlies it. That is the error.
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
"Tight coupling" slide is supposed to show a 'mess' where any component can call any other component. Which introduces a lot of other problems I'm sure you're well aware of. The "Method calls" slide simply argues that instead of allowing components to freely call each other, we define a specific contract for how they communicate. The coupling is still there, but it's clearly defined and only in one place. This makes it much easier to control, expand, and manage second-level effects. I'm also unsure if you're confused by what I refer to as a Module. A module is not one class/object. A module is a logical concept inside the monolith, grouping together many components that provide the module's functionalities.
@tuberklz
@tuberklz 2 ай бұрын
would be nice to mingle with the example source code
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Shared it on Patreon
@tuberklz
@tuberklz 2 ай бұрын
@@MilanJovanovicTech thanks
@KarthikS30712
@KarthikS30712 2 ай бұрын
Modular monoliths: Sounds like the industry's desparate cry to make developers do better OOPS and DI, PLUS relevant databases for different data models.
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
Desperate cry? We've been building modular monoliths way longer than we've been building microservices
@tempusmagia486
@tempusmagia486 2 ай бұрын
Are you stealing dometrain content? Or why is it that when they upload a course a few weeks later you upload the same topic. Is not blaming because I haven't seen this one and clean architecture with cqrs is pretty common. It is just too many coincidences
@danilousuga410
@danilousuga410 2 ай бұрын
He had said some months ago that he would talk about this topic in the future. So I mean he had planned this video before that course you've pointed out.
@yaminnather521
@yaminnather521 2 ай бұрын
Who cares though? Content creators of a similar type of content are obviously going to make videos on topics trending in their domain, right? They don't care if someone else covered a similar topic already, and why should they? It's not a big deal. The thing we should be worried about imo is whether they are making good content or not, and covering the topics well. But if the videos are the same and not just the idea of the video, then I wouldn't like it ig.
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
When throwing out serious accusations like that, I expect you to do your due diligence (which I'm sure you did, of course, why else would you accuse me of stealing without proof). So, here are a few references in case you missed them (I produce a lot of content, so I know it's easy to miss some). Here's an online talk about Modular Monoliths I held on Jan 31, 2023: kzbin.info/www/bejne/j3jFgGyaibt4bbs Here's another in-person talk I held in Norway (you'll never guess the topic) on Apr 26, 2023: kzbin.info/www/bejne/aGS0nX-tecaCe80 I have been writing about Modular Monoliths on my blog for months: - Modular Monolith Communication Patterns (August 5th, 2023): www.milanjovanovic.tech/blog/modular-monolith-communication-patterns - Monolith to Microservices: How a Modular Monolith Helps (September 23rd, 2023): www.milanjovanovic.tech/blog/monolith-to-microservices-how-a-modular-monolith-helps - Modular Monolith Data Isolation (December 9th, 2023): www.milanjovanovic.tech/blog/modular-monolith-data-isolation I've also been teasing a Modular Monolith course for months, so I have nothing to hide. Second, if you accuse someone of "stealing content" based on recency of releasing something: - My Clean Architecture course came out in August 2023 - Dometrain released two courses later that year So, who's copying who? I'm sure you'll agree this is a silly argument. I'm certainly not saying they're copying me, so why should the reverse hold true. I have a lot of practical experience using CA or MM, and I want to share my perspective. I'm confident the course will be very different from dometrain one. Third, and most important, it's a free market. If I want to release a Modular Monolith course, I can. Let the market decide which one is more valuable. Stay awesome. :)
@flygonfiasco9751
@flygonfiasco9751 2 ай бұрын
That’s a pretty serious accusation. Modular monoliths is a popular architecture right now. There’s going to be more than one content creator covering it.
@tempusmagia486
@tempusmagia486 2 ай бұрын
@@MilanJovanovicTech that's what I tried to say, I'm not blaming. I'm more like asking, maybe my words are not too clear, otherwise I would be directly reporting. I also pointed the fact that that there's no evidence
How to Structure a Modular Monolith Project in .NET
15:57
Milan Jovanović
Рет қаралды 29 М.
The Beginner's Guide to Clean Architecture
13:19
Milan Jovanović
Рет қаралды 15 М.
Ну Лилит))) прода в онк: завидные котики
00:51
1🥺🎉 #thankyou
00:29
はじめしゃちょー(hajime)
Рет қаралды 78 МЛН
Modular Monoliths: How To Build One & Lessons Learned
43:37
Milan Jovanović
Рет қаралды 39 М.
Getting Started with Event Sourcing in .NET
37:07
Nick Chapsas
Рет қаралды 42 М.
Modular Monoliths Are The New Microservices
31:08
TaleLearnCode
Рет қаралды 21 М.
Getting Started with OpenTelemetry in .NET
19:56
Nick Chapsas
Рет қаралды 46 М.
5 Rules For DTOs
17:56
Ardalis
Рет қаралды 36 М.
The pendulum swings! Microservices to Monoliths
10:29
CodeOpinion
Рет қаралды 25 М.
Distribu-ready with the Modular Monolith - Layla Porter - NDC London 2024
57:25
How to Add Health Checks in ASP.NET Core
11:51
Milan Jovanović
Рет қаралды 14 М.
Карточка Зарядка 📱 ( @ArshSoni )
0:23
EpicShortsRussia
Рет қаралды 338 М.
Pratik Cat6 kablo soyma
0:15
Elektrik-Elektronik
Рет қаралды 8 МЛН
Will the battery emit smoke if it rotates rapidly?
0:11
Meaningful Cartoons 183
Рет қаралды 951 М.
Apple, как вас уделал Тюменский бренд CaseGuru? Конец удивил #caseguru #кейсгуру #наушники
0:54
CaseGuru / Наушники / Пылесосы / Смарт-часы /
Рет қаралды 4,5 МЛН