Want to master Clean Architecture? Go here: bit.ly/3PupkOJ Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt
@davidpccode11 ай бұрын
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
@MilanJovanovicTech11 ай бұрын
Wow, thank you! This course should be a very nice extension, but much more advanced.
@JoseAlvarez-dl3hm6 ай бұрын
kind of expensive though, I would have to make some savings before buying it
@dcuccia11 ай бұрын
Should be a great course based on all the content presented so far. Looking forward to it.
@MilanJovanovicTech11 ай бұрын
Hope so! Starting work on it today 🤞😁
@theincredibleillmo938511 ай бұрын
Waiting for this course no matter what the clowns and haters say. Much love and mad respect from 🇲🇽 Mexico we! ❤❤❤
@MilanJovanovicTech11 ай бұрын
Apprecaite it, and returning the love back! 😁
@datadigger243211 ай бұрын
You are the best of the best and do not listen to silly comments Keep going ❤️❤️
@MilanJovanovicTech11 ай бұрын
Had to set the record straight 😁
@TechnicalVibs11 ай бұрын
wonderfully explained in a short way
@MilanJovanovicTech11 ай бұрын
Glad you liked it!
@pedrosilva143711 ай бұрын
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.
@MilanJovanovicTech11 ай бұрын
Yes, I agree there's a tradeoff to be made here
@umeshyeware140910 ай бұрын
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.
@MilanJovanovicTech10 ай бұрын
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.
@umeshyeware140910 ай бұрын
@@MilanJovanovicTech Thank you for quick reply
@thiagomatu11 ай бұрын
Looking forward for this next course Milan
@MilanJovanovicTech11 ай бұрын
About a ~month out from now, lots of work ahead
@qamislo974011 ай бұрын
@@MilanJovanovicTech Please hurry up with the course😊😊
@paulmdevenney2 ай бұрын
There is a third benefit of microservices, and it might be the only one a small company is interested in. Uptime. If you have a non-core service that needs changing, you can deploy only this service, while all other components remain available. So, for example, your portal and core APIs are working, but only your "create new order" functionality is minorly impared during deployment. This allows for a "zero downtime deployment" type experience (particularly if you use discovery or run-time configurable urls to point at a new service instance once available). It is amazing how often people assume "microservices = better" because big companies use them, without questioning, "why".
@MilanJovanovicTech2 ай бұрын
Technically, we can have zero-downtime deployment with a monolith also 😅 Using blue-green deployments.
@Kasiux11 ай бұрын
Milan, the best .NET/Tech KZbinr
@MilanJovanovicTech11 ай бұрын
Thanks a lot, glad you think so 😁
@PinoyDevAko11 ай бұрын
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.
@MilanJovanovicTech11 ай бұрын
It's a limitation of Teachable (the platform I'm using), so not much I can do about it :/
@PinoyDevAko11 ай бұрын
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.
@MilanJovanovicTech11 ай бұрын
@@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.
@PinoyDevAko11 ай бұрын
Thank you @@MilanJovanovicTech . Again you're wonderful and one of the best out there.
@datadigger243211 ай бұрын
Can you please milan make a video about using grpc for microservices
@MilanJovanovicTech11 ай бұрын
Will do, at some point :)
@saddamhossaindotnet11 ай бұрын
Great video, my friend 🧡
@MilanJovanovicTech11 ай бұрын
Thank you 🤗
@GuillermoValenzuela-Dev9 ай бұрын
Excellent video Milan. One question here, with modular monolith would we lose the possibility of scaling each module according to demand?
@MilanJovanovicTech9 ай бұрын
You never had the ability for granular scalability with any monolith application. It's all or nothing.
@grzegorzr362111 ай бұрын
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-xj5wf11 ай бұрын
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
@MilanJovanovicTech11 ай бұрын
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
@grzegorzr362111 ай бұрын
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?
@MilanJovanovicTech11 ай бұрын
@@grzegorzr3621 Which of the two would you choose in a microservices system?
@grzegorzr362111 ай бұрын
@@MilanJovanovicTech I don't know. I don't know about this.
@marklnz9 ай бұрын
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!
@MilanJovanovicTech9 ай бұрын
Dumbest take ever 😂
@marklnz9 ай бұрын
@@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.
@AravindhKumar0077 ай бұрын
I do feel the same... just by enforcing that monolith code now will not be horizontal does not increase the efficacy magically. If you already have the infrastructure to manage and operate a Microservice - that's clearly the best. If you can manage the Microservice at par, then Nano service would be the way.
@AravindhKumar0077 ай бұрын
Look at the Figma Database issues, you'll know what I'm speaking. Vertical scaling is not an effective scaling. It has an upper ceiling.
@marklnz7 ай бұрын
@@AravindhKumar007 Careful, don't go having a different opinion to the OP - he's going to tell you it's a dumb take. This guy is a hack and there's no point engaging with him.
@datadigger243211 ай бұрын
Great video milan thanks
@MilanJovanovicTech11 ай бұрын
Glad you enjoyed it :)
@HomeSlize9 ай бұрын
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!
@MilanJovanovicTech9 ай бұрын
The 7 lessons are from the bonus course. It's a condensed version of the main one, from a slightly different angle.
@yaminnather52111 ай бұрын
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
@MilanJovanovicTech11 ай бұрын
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.
@yaminnather52111 ай бұрын
@@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 :)
@MilanJovanovicTech11 ай бұрын
@@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.
@AkosLukacs4211 ай бұрын
@@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.
@yaminnather52111 ай бұрын
@@MilanJovanovicTech Yeah that makes sense. Thanks.
@jakelanning15357 ай бұрын
How do you deal with the desire for a foreign key between users and orders, or between orders and catalog? I feel like the user who made an order or the catolog item id for the that item that was ordered are entities where the referential integrity that foreign keys offer would be a requirement. Plus the EF migration properties would be pretty convenient!
@jakelanning15357 ай бұрын
EF navigation properties! Not migration lol.
@MilanJovanovicTech7 ай бұрын
In a single database, keeping FK constraints is fine. It only becomes a problem when you want to split the database apart when extracting a module. In that case, break the FK and continue. But you can also implement everything without FK constraints, and have your application logic enforce this. How do we maintain this in a distributed system? We don't. As the databases are distributed. We trust that an ID from a different system belongs to an existing record.
@supremedev485111 ай бұрын
Great video. Thanks 👍
@MilanJovanovicTech11 ай бұрын
Thank you very much! :)
@EugeneZavalko11 ай бұрын
Great explanation
@MilanJovanovicTech11 ай бұрын
Glad you liked it
@alexandrehando11 ай бұрын
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!
@MilanJovanovicTech11 ай бұрын
Coupled stuff goes together, check my longer videos on Modular Monoliths.
@marko95g9 ай бұрын
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?
@MilanJovanovicTech9 ай бұрын
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.
@marko95g9 ай бұрын
@@MilanJovanovicTech this can be very very complex..thanks!
@hugobarroca95389 ай бұрын
Good explanations and clear graphics! Good work on the video! 🙂
@MilanJovanovicTech9 ай бұрын
Thank you! 😃
@alexandrehando10 ай бұрын
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!
@MilanJovanovicTech9 ай бұрын
Implement that functionality in a single module?
@BrandonAllen-v7f11 ай бұрын
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?
@MilanJovanovicTech11 ай бұрын
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?
@KingOfBlades2711 ай бұрын
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 🤔
@MilanJovanovicTech11 ай бұрын
I wouldn't consider that a modular monolith
@erradil11 ай бұрын
Great thanks. could have access to the demo repository
@MilanJovanovicTech11 ай бұрын
It's shared on Patreon
@alejomillo774411 ай бұрын
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?
@MilanJovanovicTech11 ай бұрын
Yes
@nanvlad11 ай бұрын
Is message broker running outside of the process of monolith app? Or is it just a logical module to communicate between layers like MediatR?
@MilanJovanovicTech11 ай бұрын
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
@raycarlbrown-amory350911 ай бұрын
fantastic video
@MilanJovanovicTech11 ай бұрын
Thanks a lot! :)
@bobek803011 ай бұрын
How you separate di containers for modules?
@MilanJovanovicTech11 ай бұрын
You don't necessarily have to. And the built-in DI doesn't support that. You have to use something like Autofac.
@cartongessow1011 ай бұрын
what tool did you use for diagrams?
@MilanJovanovicTech11 ай бұрын
Excalidraw for the "shiny ones" and draw.io for the C4 diagrams (but you can do C4 diagrams in other tools)
@dannym81710 ай бұрын
Can we see somewhere all code? Like in github?
@MilanJovanovicTech10 ай бұрын
I share all the source code on Patreon, and for some videos you can find it in the description
@DanielCipra11 ай бұрын
What is up with the Bind and Tap methods? Is that from some nuget package?
@MilanJovanovicTech11 ай бұрын
Sorry 'bout that 😅 I was applying ROP on this project.
@phw100911 ай бұрын
Master..... I will join the modular side of the force...
@MilanJovanovicTech11 ай бұрын
Come to the, erm..., modular side? 😂 lol
@piotrwrotny97036 ай бұрын
Hey man. I'm from Poland, currently working as data sth. I want to start my career as .NET dev. In my current company, I've got budget for one of Your courser. What in Your opinion is a better take, for someone who's programming for few years, and want to start a new role as .NET dev? Both courses seems very powerful, but with in Your opinion would look better at resume? I'm willing to buy both, but the first will be from my current employer money 😀 could You give me Your take on this?
@MilanJovanovicTech6 ай бұрын
Buy the more expensive one? 😅 Do you have experience with .NET from before? As both courses expect some level of familiarity with the .NET tooling (runtime, framework, IDE). Feel free to send me an email - milan @ milanjovanovic.tech if you want to discuss this in more detail.
@piotrwrotny97036 ай бұрын
@@MilanJovanovicTech TY man! I will refer to this comment into email. But the decision might be simple as that - let the company buy the more expensive one 😁
@Cornet43511 ай бұрын
How can one module fetch data from another?
@MilanJovanovicTech11 ай бұрын
Read this: www.milanjovanovic.tech/blog/modular-monolith-communication-patterns I'll release a few more videos soon.
@vincentcifello443511 ай бұрын
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.
@MilanJovanovicTech11 ай бұрын
"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.
@sunzhang-d9v11 ай бұрын
love
@MilanJovanovicTech11 ай бұрын
Thanks!
@artemvolsh3877 ай бұрын
Like for the 100$M Leads book)
@MilanJovanovicTech7 ай бұрын
It's a great book 😁👌
@tuberklz11 ай бұрын
would be nice to mingle with the example source code
@MilanJovanovicTech11 ай бұрын
Shared it on Patreon
@tuberklz11 ай бұрын
@@MilanJovanovicTech thanks
@KarthikS3071210 ай бұрын
Modular monoliths: Sounds like the industry's desparate cry to make developers do better OOPS and DI, PLUS relevant databases for different data models.
@MilanJovanovicTech10 ай бұрын
Desperate cry? We've been building modular monoliths way longer than we've been building microservices
@tempusmagia48611 ай бұрын
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
@danilousuga41011 ай бұрын
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.
@yaminnather52111 ай бұрын
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.
@MilanJovanovicTech11 ай бұрын
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. :)
@flygonfiasco975111 ай бұрын
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.
@tempusmagia48611 ай бұрын
@@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