Domain Modeling with Domain-Driven Design (From Scratch)

  Рет қаралды 27,558

Milan Jovanović

Milan Jovanović

Күн бұрын

Пікірлер: 97
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Want to master Clean Architecture? Go here: bit.ly/3PupkOJ Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt
@EvekoShadow
@EvekoShadow 7 ай бұрын
Would there be any downsides to using Entity and then use a strongly typed Id when extending User : Entity
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
Other than the complexity?
@alexmadnix
@alexmadnix Жыл бұрын
Thank you. Milan I've been using C# for a long time, but I've rarely utilized unit testing, so it's something I'm still pretty low on, but after taking the course, I've gained a lot of confidence in it.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Have another video on unit testing coming out soon :)
@aweklin
@aweklin Жыл бұрын
Hi Milan, glad you posted this. Have added something new to my knowledge base. Will ensure I follow through the series. Hope it's going to be in its own playlist 😊 Thanks a million.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Let me make a playlist for this then!
@benjaminvenezia1944
@benjaminvenezia1944 Ай бұрын
This is pure gold
@MilanJovanovicTech
@MilanJovanovicTech Ай бұрын
Thanks a lot!
@RiwenX
@RiwenX 11 ай бұрын
This is great. Please consider creating playlists for those of us who are kinda lost
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
Good suggestion 😅
@sesh3219
@sesh3219 Жыл бұрын
Thank u so much. Hyped for the modular monolith series!
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Hope you enjoy it!
@ibrahimhebish7744
@ibrahimhebish7744 Жыл бұрын
You are doing a great job 👍 Milan, Keep it up.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Appreciate it! :)
@nove1398
@nove1398 Жыл бұрын
This is a great approach for the topic. Lots of useful information here, got a few gems from this video
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Glad it was helpful! This will be a fun series of videos :)
@TheBadspeed
@TheBadspeed Жыл бұрын
Amazing video, can't wait for the next ones!
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
I've got a fun series lined up 😁
@joehernandez3231
@joehernandez3231 Жыл бұрын
Nicely done. Looking forward to more videos related to the activity tracker.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Coming soon!
@matheustorresdosreis9508
@matheustorresdosreis9508 Жыл бұрын
Amazing Milan, looking forward to see how to read the values from domain events
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Already have a few videos in the past about this, check them out
@ilovepandaypoe6056
@ilovepandaypoe6056 Жыл бұрын
What is the advantage of using an abstract instead of interface for the entity class?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
The lines are blurred because you can also define default implementations in interfaces. But abstract classes can have internal state.
@adahadapato
@adahadapato 11 ай бұрын
thank you for putting this together, please how do I use this Entity base class with entities that have keys named differently from Id. say Code, etc
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
You can configure that with EF
@julienlefevre1661
@julienlefevre1661 9 ай бұрын
Very good video with practical example, clear explainations. Thanks!
@MilanJovanovicTech
@MilanJovanovicTech 9 ай бұрын
Glad it was helpful!
@dmytroshchotkin2939
@dmytroshchotkin2939 Жыл бұрын
4:11 I don't get it. You've created a public ctor in which you're accepting a nullable string argument BUT you're immediately throwing an exception if a 'null' is passed. Why did you make the argument nullable then? You need to do it ONLY if 'null' IS a valid value for the parameter. Otherwise you should explicitly declare that you expect non-null value and to throw an exception if you get 'null'.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Just a guard clause example, gets cleaned up later
@ferventurart
@ferventurart Жыл бұрын
Which tool is used to do the diagrams?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Excalidraw
@caseyspaulding
@caseyspaulding Жыл бұрын
Thanks. This was a great lesson. Keep it up.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Glad you liked it!
@KrelleTG
@KrelleTG Жыл бұрын
Hi Milan. How would you raise a domain event for a deletion, like you have with Create?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Call a "Cancel/Delete" method on the entity and raise a domain event
@KrelleTG
@KrelleTG Жыл бұрын
@@MilanJovanovicTech But when would you do this? In this case you call it on example.Create(), but you do not necessarirly have a domain entity in delete. Would you call it in a service layer?
@chuo129
@chuo129 Жыл бұрын
Dear. Millan, excellent work. Have you considered make a video about multitenancy? Thanks
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Yes, soon
@canodev
@canodev Жыл бұрын
Which tool do you use to create the diagrams?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Excalidraw
@musazulu7013
@musazulu7013 Жыл бұрын
Thanks a lot @MilanJovanovicTech this is awesome can we please have the entire series related to this
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Working on it!
@ZubriQue
@ZubriQue Жыл бұрын
I have just Models from my DB. How to know which of them are Entities, Valueo Objects or Aggregates?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Reading the DDD book is a good start
@ZubriQue
@ZubriQue Жыл бұрын
@@MilanJovanovicTech Thank you for the answer! I am half way through it as I figured out what a Value Object is at least.
@peterblomqvist227
@peterblomqvist227 Жыл бұрын
Thank you for once again a very good and pedagogic video. I like them all. I have a different situation. We have an old, quite large, database. And I want to refactor the systems around it. My approach is to add a database model (classes reflecting the database who are created by scaffolding), in the infrastructure project together with mappings to and from the new domain model I want to build. I know that it's not optimal adding another DTO layer which also adds complexity. But I don't know what else I could do. A mapping from the database (with Fluent API) to the domain model will be quite complicated (because the db model and the domain model will be so different) and I'm not sure if it's possible to do. Do you have an opinion how to implement a (DDD) domain model for an existing database or another approach to my problem? I must also mention that the primary keys are not GUIDs, they are integers and many times identity columns.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Your approach is fine. The cost is added complexity and more code to maintain. But as long as you have a clear mapping from DB model to Domain model (and vice-versa) - you're on the right track.
@peterblomqvist227
@peterblomqvist227 Жыл бұрын
@@MilanJovanovicTech 👍Thank you Milan. That was good to hear from an external person 😊 I'm trying to use Mapperly for the mapping part. But it's hard to use with value objects. I can't get it to work... I haven't seen any video or found any webpage explaining how that is done. I'll continue checking your great videos and get good ideas from you. Thanks again for the job your doing!
@pavelkobjakov4148
@pavelkobjakov4148 Жыл бұрын
Why in Name record we are use nullable type in constructor? If I want to create an instance of the Name record then i'll expect that i can pass NULL to Name record, because it accept a nullable type and VS studio don't show me, that i wrong, because constructor accept nullable string but in runtime i get exception
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Compile-time and runtime constraints behave differently
@pavelkobjakov4148
@pavelkobjakov4148 Жыл бұрын
@@MilanJovanovicTech do I understand correctly that in this way we lose the possibility of hints from the IDE and get an error (warning) not at the compilation stage, but in runtime? What is the advantage of this approach?
@Alexander-zt9kz
@Alexander-zt9kz 6 ай бұрын
I am new to DDD, modular monoliths, and designing microservices. Are the modules in your monolith the same as what should be it's own microservice? IE, we have an excercise and a workout module, so would we have an excercise and workout microservice if we were to use microservices?
@Alexander-zt9kz
@Alexander-zt9kz 6 ай бұрын
Great video btw 😁
@MilanJovanovicTech
@MilanJovanovicTech 6 ай бұрын
Module = bounded context (one way to look at it). Which translates very nicely to a microservice.
@RMarjanovic
@RMarjanovic Жыл бұрын
What are your thoughts on passing primitive types in the static factory methods instead of Value Object types? I find that I'm cluttering and needing to check lots of results in my use cases before I can actually create the entity / aggregate root. Instead I move the logic of creating value objects to the entity and can combine the results using your railway oriented implementation.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
I like to assume that everything has been checked by the time I hit my domain entities. But I'm totally not against your approach. I can see how it simplifies the use cases, and moves more of the responsibility to the domain.
@RMarjanovic
@RMarjanovic Жыл бұрын
@@MilanJovanovicTech After using this for a while and testing with a profiler I noticed that for my usecases I recreate the strongly type id value objects a lot by using this approach. Which caused some performance hits. I refactored to use your approach instead.
@keithjairam8452
@keithjairam8452 Жыл бұрын
Love your content…keep it up.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Glad you enjoy it!
@KrzysztofBarbarski
@KrzysztofBarbarski Жыл бұрын
Great video, Milan, does You consider making video about how to deploy app into production? This would be great supplementation of your Clean Architecture course. Without any doubt, i would like to see how You deploy your built on docker app into production using for ex. Azure.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
That's an awesome suggestion! I have a CI video coming out soon, but I'll work on a deployment one afterwards. In the meantime, there's this: kzbin.info/www/bejne/h4GToZxtrcplatU
@nickst0ne
@nickst0ne Жыл бұрын
I love the strongly-typed properties like the user's name in this video. But I have difficulty setting up the persistence of entities for such properties. I know I've seen it done in one of your videos but it requires a full control on the context, which is something I didn't have in one project where it was database-first and the scaffolding was configuring the context. I think the persistence of strongly-typed ids/properties would deserve a video of its own, considering the different ORMs or approaches.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
I think you should be able to make it work with fluent config in EF Core?
@pity7736
@pity7736 Жыл бұрын
Nice video. Thank you! I have a question: is ok to send that domain event just for instantiating the User entity? What should be the case when User entity is creating a object just because a query from UserRepository? You're not creating a User itself, just instantiating the entity. Thanks!
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
It's ok to send that domain event just for instantiating the User entity
@pity7736
@pity7736 Жыл бұрын
@@MilanJovanovicTech But every time? Imagine that you need to send a welcome email to the user when is created in the system. In that case is perfect. But, imagine that you query that user from database to make login, for example, that domain event will be raised too and the welcome email will be sent. In this case is not so good.
@richardhaughton9633
@richardhaughton9633 Жыл бұрын
Hi Milan. Please show us how to correctly configure DDD with EF Core. I always have trouble with private setters and constructors
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
This should help: kzbin.info/www/bejne/f527n3yba9WSi80
@fiqrihafzain2820
@fiqrihafzain2820 Жыл бұрын
can domain modeling to do something like this in clean architecture? data class DevByteVideo(val title: String, val description: String, val url: String, val updated: String, val thumbnail: String) { val shortDescription: String get() = description.smartTruncate(200) }
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Why not?
@techpc5453
@techpc5453 Жыл бұрын
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
👋
@phennexion
@phennexion Жыл бұрын
Maybe im just too much of a newbie, but why all this added complexity?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Showcasing DDD
@dputra
@dputra Жыл бұрын
The point of ddd is in the effort to align software development (technical) with your users' business cases (domain). You are building a bridge between the developers and the users, creating better communication and collaboration. The first step to achieve this is to identify the "domain" of your user business. What is the entities that will be in the business? What can you do with them? It's necessary to use the proper term, according to your users, of your entity classes. Because keeping the domain knowledge is important in DDD, we have to build a whole structure of projects that builds around those entities. DDD shines if you have expert users and many developers with knowledge gap between them.
@phennexion
@phennexion Жыл бұрын
@@dputra interesting, thanks for that reply. So I'm guessing it's really good for when a company outsources it's development and helps the developers understand what they're trying to do better?
@dputra
@dputra Жыл бұрын
I gave up with youtube keep deleting my replies 😫
@dputra
@dputra Жыл бұрын
@@phennexion It's even impossible for the internal IT team to know exactly the business needs. Softwaremill wrote a good article about DDD. Just google it! 😁
@lexuantruong3835
@lexuantruong3835 Жыл бұрын
That looks like an application service rather than a domain service
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Why?
@petewarner1077
@petewarner1077 Жыл бұрын
It is not true when you say "Name cannot be null" for the static factory method on User just because the parameter type is not marked as nullable. The consumer can explicitly call User.Create(null), ignoring any warnings and the intent of the method. This is exactly the scenario where you *do* want a guard clause. Conversely, the nullability of the value parameter of the Name record should *not* be nullable since you have a guard that will throw if the consumer does pass null.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Easily solvable with nullable reference types and some code analyzers
@petewarner1077
@petewarner1077 Жыл бұрын
​@@MilanJovanovicTech Sorry Milan, I didn't understand your reply. Trying to clarify my own comment: In your video, you have a nullable reference type, and guard against it being null. You also have a non-nullable reference type but don't guard against that being null. You state that the Name value passed to the factory method cannot be null - it can. It's not a struct.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
@@petewarner1077 Conceptually, yes - it can be null. But in any normal execution flow it will never be null. And I'm saying you can guard against this with nullable reference types + code analyzers. You can turn "treat warnings as errors" and the build will never pass if you're trying to pass null for a non-nullable value. Does that make sense?
@enciphered7650
@enciphered7650 Жыл бұрын
I find no utility is doing so much work. Hopefully future videos makes it clear the benefits.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
If you don't see any value in DDD, it probably won't make sense
@erandafernando94
@erandafernando94 6 ай бұрын
fuck im dumb
@MilanJovanovicTech
@MilanJovanovicTech 6 ай бұрын
Why do you say that?
@erandafernando94
@erandafernando94 6 ай бұрын
@@MilanJovanovicTech quite hard to catch up lol. had to watch few times. but keep them coming! if u can dumb it down a bit, that would great!
@Athurito
@Athurito Жыл бұрын
I dont like nested classes xD
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Easy to clean up 😁
Modeling a Domain With Domain-Driven Design From Scratch | DDD
19:10
Milan Jovanović
Рет қаралды 94 М.
Mapping Domain-Driven Design Concepts To The Database With EF Core
18:06
Milan Jovanović
Рет қаралды 55 М.
UFC 310 : Рахмонов VS Мачадо Гэрри
05:00
Setanta Sports UFC
Рет қаралды 1,2 МЛН
Cat mode and a glass of water #family #humor #fun
00:22
Kotiki_Z
Рет қаралды 42 МЛН
How To Use Domain-Driven Design In Clean Architecture
30:27
Milan Jovanović
Рет қаралды 113 М.
Domain-Driven Design: The Last Explanation You'll Ever Need
21:05
Software Developer Diaries
Рет қаралды 15 М.
What is the Shared Kernel in Domain-Driven Design?
12:10
Milan Jovanović
Рет қаралды 11 М.
How to Use the Domain Event Pattern | DDD, Clean Architecture, .NET 6
9:48
How to Implement the CQRS Pattern in Clean Architecture (from scratch)
17:36
Onion Architecture vs Clean Architecture Comparison
13:44
Milan Jovanović
Рет қаралды 47 М.
Get Rid of Exceptions in Your Code With the Result Pattern
13:06
Milan Jovanović
Рет қаралды 57 М.
EF Core 8 Finally Fixes Value Objects
11:25
Milan Jovanović
Рет қаралды 27 М.