What Is An Entity? | Domain-Driven Design, Clean Architecture, .NET 6

  Рет қаралды 46,235

Milan Jovanović

Milan Jovanović

Күн бұрын

Пікірлер: 131
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Get the source code for this video for FREE → the-dotnet-weekly.ck.page/entity Want to master Clean Architecture? Go here: bit.ly/3PupkOJ Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt
@flobuilds
@flobuilds 2 жыл бұрын
I'm glad i found your channel. I hate all these "beginner" or standard videos where they always show code that would never be in production but this is some quality stuff thanks 💯
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
This is kind of the gap that I also noticed, and one I'm trying to fill. By the end of this series we will have created a nice production ready application 😁
@flobuilds
@flobuilds 2 жыл бұрын
@@MilanJovanovicTech thanks for the great work seeing forward to the end and the stuff that comes after that😃 im currently building a production ready system for our startup but im just learning by doing and if you don't find good articles or videos to learn the good stuff you have a big problem
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
@@flobuilds Anything that would benefit you in particular?
@flobuilds
@flobuilds 2 жыл бұрын
@@MilanJovanovicTech at the moment im building the complete auth server with all the user functionalities, refresh tokens etc. But after that service i want to implement all other functions with microservices for our system because its modern and will later be way easier to do maintenance. And it would be nice to find something in depth about microservices like the complete implementation with docker/kubernetes and the code itself and the api gateways and maybe backend communication like rabbit mq
@ZeeshanAli-ll6ki
@ZeeshanAli-ll6ki 2 жыл бұрын
@@MilanJovanovicTech Can you add implementing auth functionality along with refresh token in your future videos along with concepts like mapping the data from jwt token to profile class and then using that class inside other endpoints.
@nicholasslodki703
@nicholasslodki703 Жыл бұрын
Your monolog with these is excellent and demonstrates a masterful command of both English and the rest of this stuff.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Thanks a lot :)
@chrismingay6005
@chrismingay6005 2 жыл бұрын
you've got a great way of explaining things. I'm by no means a beginner anymore but your videos are always a great refresher, I really appreciate your effort with these
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
I appreciate that Chris, thank you!
@armanbecirovic2238
@armanbecirovic2238 4 ай бұрын
Have to admit this CA&DDD series is fantastic! Very well explained step by step with logical explanation and why something is a good practice. I started to like DDD just by watching your videos. Thank you Milan! 👏💪
@MilanJovanovicTech
@MilanJovanovicTech 4 ай бұрын
Glad you enjoyed it!
@kinggrizzly13
@kinggrizzly13 2 жыл бұрын
I love the simplicity of following YAGNI principle for your example. Many books and examples throw you a lot of boilerplate code that may not be necessary when learning DDD techniques. Thanks for sharing.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
I had to follow those many book and examples to be able to explain it simple like this 😅 Hopefully this speeds up others learning about DDD
@andergarcia1115
@andergarcia1115 3 ай бұрын
I hope to be like you one day. Thanks for being an inspiration
@MilanJovanovicTech
@MilanJovanovicTech 3 ай бұрын
You can do it!
@modernkennnern
@modernkennnern Жыл бұрын
3:10 This might be late, but as long as you only initialize it in the constructor you don't even need a setter. `public Guid Id { get; }` is enough.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
True
@Eamo-21
@Eamo-21 2 жыл бұрын
Awesome Milan! I see you on Twitter often but not KZbin
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Hopefully the algo starts showing me some love 😁
@sushilb7994
@sushilb7994 2 жыл бұрын
Nice video, Milan. Your videos are awesome because you keep it simple and go over from basic to advance concepts. Love this format. Keep it up!!!
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Thank you, I'm really glad you are liking the channel so far. More great videos are coming 😊
@nickolaki
@nickolaki 2 жыл бұрын
You cheeky boy putting this out today rather than tomorrow. 😉Great job Milan!
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
But I am aiming for Tuesday-Thursday anyhow 🤷‍♂️
@tidianediallo6199
@tidianediallo6199 2 жыл бұрын
😊😊
@ugochukwuumerie6378
@ugochukwuumerie6378 2 жыл бұрын
Awesome! Keep 'em coming. I see people using like an aggregate root to define the entity id
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
I think the line is kind of blurry between them. I prefer not applying the AggregateRoot pattern, as I tend to end up with big aggregates with a lot of logic. Also, just because the pattern exists doesn't mean you have to use it. 😁
@ugochukwuumerie6378
@ugochukwuumerie6378 2 жыл бұрын
@@MilanJovanovicTech thanks alot 🙏, I appreciate, its much more clearer now
@ipelengmekgwe834
@ipelengmekgwe834 7 ай бұрын
Your videos are so informative, thank you!
@MilanJovanovicTech
@MilanJovanovicTech 7 ай бұрын
You are so welcome!
@anthonytrad
@anthonytrad 2 жыл бұрын
Great video, a small heads-up nevertheless: Using Guids directly for ids may be considered as a primitive type obsession... You're setting the fundamentals and you didn't talk about value objects yet, but I think this should be mentioned because It will affect your base Entity implémentation. I think PTO is a key concept if we're doing DDD soo that's just my thoughts.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
That's a great observation. I'm covering ValueObjects in one of the future videos, and also talking about Primitive Obsession. However, I didn't touch on strongly typed Ids. I'm thinking of making a separate video on that topic, now that you mentioned it.
@tiagocandeias3969
@tiagocandeias3969 2 жыл бұрын
If we go down the "Primitive type obession" rabit hole you wont even have strings and int in the entities :) Or is it anything specific for GUID's that I'm missing
@anthonytrad
@anthonytrad 2 жыл бұрын
@@tiagocandeias3969 I was mainly referring to strongly type IDs. We don't apply PTO on every property, the FirstName for example can stay a string but if you were to add an address then it might be better as a value object. Applying it everywhere would be insane;)!
@kinggrizzly13
@kinggrizzly13 2 жыл бұрын
Totally agree, as I’d make my Id a ValueObject as well.
@MrKlyushin
@MrKlyushin Жыл бұрын
Hello, Milan, You made your Gathering class as sealed. My sonarsource tells me of a bad smell RSPEC-4035 Tells me - Classes implementing "IEquatable" should be sealed Is it okay if I remove sealed because I need to have inheritance? And I also don't get if a "domain layer" can have an interface folder for interfaces for entities. Example: I've got hierarchy: BaseMaterial -> Material, PackMaterial and all of them implement IMaterial interface in which I guarantee that all classes that implement it have some fields and some methods I expect them to have.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
If you need inheritance, of course
@MrKlyushin
@MrKlyushin Жыл бұрын
@@MilanJovanovicTech thx! 👍
@tidianediallo6199
@tidianediallo6199 2 жыл бұрын
I am very happy to find this channel and the explanations are clear and precise and I look forward to the next videos. A big thank-you. Just a question M Milab: How do you choose the naming of the folders and what they should contain, for example the primitive folder?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Hi, and welcome to the channel! 😁 Copying the answer from another thread: So using "Abstractions" and "Primitives" for these kinds of common/base types is something I picked up from Microsoft. If you notice how they create their namespaces, interfaces and types are usually defined in a namespace ending with either ".Abstractions" or ".Primitives"
@coding-in
@coding-in 2 жыл бұрын
Yu are right! He's keep to explain what he's writes..
@9_vko
@9_vko 2 ай бұрын
Nice tutorial! On the other hand I would add more details information about what's difference between Anemic Domain Model and Rich Domain Model approaches. In which case we need to pick the Anemic Domain Model or Rich Domain Model ?
@MilanJovanovicTech
@MilanJovanovicTech 2 ай бұрын
I made a separate video on that
@9_vko
@9_vko 2 ай бұрын
@@MilanJovanovicTech Awesome! 😎
@سهیلداودی-ص1ف
@سهیلداودی-ص1ف 2 жыл бұрын
Why do We have to check equality between two objects in DDD, Thanks for video and please keep posting videos
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
How else would we know if two entities are the same?
@garethcraig8902
@garethcraig8902 6 ай бұрын
Really great video. My only concern is the use of Guid's. I work in the online gaming industry and we have an extremely high transaction rate, thousands of bets a minute. Guids have not fared very well and we have been actively removing them for smaller data types. Not sure how we would apply this, with say a INT or Short data type.
@MilanJovanovicTech
@MilanJovanovicTech 6 ай бұрын
You probably don't generate those values client-side?
@ujuzitek301
@ujuzitek301 Жыл бұрын
Hi Milan, what is the logic by multiplying the GetHasCode method by a prime number?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Provides a more even distribution of the hash code, nothing fancy though
@Yosso117
@Yosso117 2 жыл бұрын
Братан, хорош, давай, давай, вперёд! Контент в кайф, можно ещё? Вообще красавчик! Можно вот этого вот почаще?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
More about DDD or more about Entities?
@LilPozzer
@LilPozzer 6 ай бұрын
extreme code
@paulbarton2280
@paulbarton2280 2 жыл бұрын
Will you be covering Aggregates? It seems even with this simple domain, if for example a Gathering was to be canceled this would effect other Entities/Value Objects.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
I'm still uncertain about that one Paul. Not sure if I just want to continue with Domain Events, or tackle it from an Aggregate perspective. Going to decide this weekend anyway 😁
@paulbarton2280
@paulbarton2280 2 жыл бұрын
@@MilanJovanovicTech I understand. Is there a reason you did not make the Id property of your Entity class a Value Object?
@krccmsitp2884
@krccmsitp2884 2 жыл бұрын
@@paulbarton2280 Guid is a struct which already has the behavior the Value Object pattern would give.
@MarincaGheorghe
@MarincaGheorghe Ай бұрын
A question. Why would you need to compare entities in your domain: collision or what? Who would need to use equality on these ?
@MilanJovanovicTech
@MilanJovanovicTech Ай бұрын
Semantics
@huynhtriet444
@huynhtriet444 Жыл бұрын
Hi Milan, really great information here! Just one question when you implement the Equal(Entity? other) method. Since you already have the Equal(object? obj) method, can't you utilize this when you create the Equal(Entity? other) as well? Something like this " public bool Equals(Entity? other) { return Equals(other); }". I want to know if this is the same or I am missing something. Thank again for your work!
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
You'd have to cast it to an object, so that's one downside, otherwise it's possible
@vertikalniserklaz8694
@vertikalniserklaz8694 Жыл бұрын
This is cool and very helpful, however, I haven't found an explanation in any of your videos on how to perform entity validation that require any interaction with DB (e.g. duplicate user name). Naturally, this type of validation should be encapsulated in an entity but, of course, you won't inject a repository into an entity to check duplicates.
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
There's a video on user registration and validating duplicate emails that I'm sure you'll enjoy
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
4 Ways To Do Email Uniqueness Check, let me know what you think after watching
@vertikalniserklaz8694
@vertikalniserklaz8694 Жыл бұрын
​@@MilanJovanovicTech as long as we stick to the previously defined standard, it is fine. I found many times people are doing validation that involves DB calls in DomainService class which leads us to an anemic domain model (entity), though sometimes. Btw, can you point to the video where you explained CreateMemberCommandHandler and Domain Services?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
@@vertikalniserklaz8694 kzbin.info/www/bejne/m3SaeIB9frdnfdk
@dandoescode
@dandoescode Жыл бұрын
How would this approach change if you are using strongly typed IDs for your entities. Would you still need this base Entity functionality?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
It becomes quite a bit verbose, honestly. Entity has to be generic, and you need to solve strongly typed ID equality as a generic argument. Amichai had an interesting take in a recent video
@tanvirarjel
@tanvirarjel 2 жыл бұрын
Good work! MIlan, Continue please! However, I have a question. What is your thought process behind naming the folder 'Primitives'?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
That's a great question. So using "Abstractions" and "Primitives" for these kinds of common/base types is something I picked up from Microsoft. If you notice how they create their namespaces, interfaces and types are usually defined in a namespace ending with either ".Abstractions" or ".Primitives"
@tanvirarjel
@tanvirarjel 2 жыл бұрын
@@MilanJovanovicTech Good spot!
@aseneda
@aseneda 2 жыл бұрын
Great content and didactic Milan, congrats! Could I suggest a Builder creational pattern in case of complex Entity. Next video will be Object Value :) ? Best regards
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Next video will be Domain validation. Followed by Value Object, Aggregates, Domain Events... 😁
@imaynedlog9628
@imaynedlog9628 Жыл бұрын
Why do you need init in Entity class? Because we set ID using constructor anyway, we just need readonly ID property, don't we?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Make it easier when materializing entity
@afermeherremova5672
@afermeherremova5672 Жыл бұрын
If all my entities use different data types for their ID, is it acceptable to convert the Entity class to a generic type?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
You can - but beware of how you will use that Entity in any generic context
@zheniachubarov3384
@zheniachubarov3384 10 ай бұрын
Does EF Supports init modifier?
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
Yes
@pigrebanto
@pigrebanto 11 ай бұрын
Good stuff! Why you have 2x Equals methods in the Entity class? isn't the one on the Entity (Equatable interface) enough?
@MilanJovanovicTech
@MilanJovanovicTech 11 ай бұрын
One is object.Equals and one is IEquatable.Equals
@dhanushshetty7840
@dhanushshetty7840 2 жыл бұрын
Is there going to be more refactoring so that we can execute moq frameworks to unit test?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
I will tackle testing at some point for sure.
@dhanushshetty7840
@dhanushshetty7840 2 жыл бұрын
@@MilanJovanovicTech thanks Milan
@ivandrofly
@ivandrofly Жыл бұрын
thanks
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
You're welcome!
@sinafallahpour2626
@sinafallahpour2626 Жыл бұрын
very good video
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Thanks!
@jimkoro664
@jimkoro664 2 жыл бұрын
Hi Milan. Why not let the base Entity instantiate the Id in the ctor or the prop. What's the benefit of passing it via ctor parameter only to use .NewId in every case?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
You are going to get some funny behavior if you use EF as your ORM. EF calls the constructor that it deems appropriate when materializing entities. So that ctor that sets the Id may get called on every read from the DB, so you will end up with a random Id on each try. Be careful with that one.
@HajvazS
@HajvazS 2 жыл бұрын
Hi Koro, you can do this, but you have to make the set of the Id property public, so ef core will overwrite the instantiated Id whe materializing entities. Maybe you can try to have two constsructors, one for creating new entities, and the other one for existing entities and test how EF is handling this.
@bohdankatrychenko2479
@bohdankatrychenko2479 Жыл бұрын
Aren't the if statements when you compare obj.GetType() and that object is an Entity check the same thing?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
What guarantees that they are the same type?
@bohdankatrychenko2479
@bohdankatrychenko2479 Жыл бұрын
​@@MilanJovanovicTechI'm not completely sure, but I think that GetType comparison guarantees that they're the same type. And the second if statement is not really needed, you could just type cast the object to the entity like this: Entity entity = (Entity)obj
@iliyan-kulishev
@iliyan-kulishev 2 жыл бұрын
I started watching your videos all the way from the oldest. I really like what DDD brings, but can't we avoid having ids as Guids ? Can't I just rely on DBMS and the autoincrement mechanism there ?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Absolutely, there's no reason you can't go with that. This was just a design decision at the time
@ivandrofly
@ivandrofly Жыл бұрын
1:03 - Definition* of Entity
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Indeed
@microtech2448
@microtech2448 Жыл бұрын
Can we make an entity that has a generic type rather than Guid? Because some entities may have primary keys as integer, some may have bigint, some may have Guid etc.. if yes, then how. Thanks!
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Of course, just more boilerplate
@microtech2448
@microtech2448 Жыл бұрын
​@@MilanJovanovicTechcan you post something on this as community post?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
@@microtech2448 Sure 😁
@microtech2448
@microtech2448 Жыл бұрын
@@MilanJovanovicTech thanks 🙂
@mahmoudalballah3387
@mahmoudalballah3387 Жыл бұрын
Awesome!
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Should I do more DDD content? 😁
@imaynedlog9628
@imaynedlog9628 Жыл бұрын
Also, why do you use an "Entity?" This is a class, so it can be null anyway? Or it for other developers? Your VS doesn't recommend you remove "?" because this isn't a value object?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
Just making things explicit
@imaynedlog9628
@imaynedlog9628 Жыл бұрын
​@@MilanJovanovicTechThank you very much for answering)
@nikolaignjatovic6788
@nikolaignjatovic6788 2 жыл бұрын
Nice video. Why 41?
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
41 is a prime number. When multiplying with a prime number you are more likely to produce an even distribution of hash codes across hash buckets. Resulting in less hash colisions.
@nikolaignjatovic6788
@nikolaignjatovic6788 2 жыл бұрын
@@MilanJovanovicTech Thank you Milan. :)
@vikontart
@vikontart 2 жыл бұрын
@@MilanJovanovicTech I think that we need to extract this magic number 41. Create a const variable and describe it. What do you say?
@sinafallahpour2626
@sinafallahpour2626 Жыл бұрын
im from iran and i cant pay $ for you from iran . how to access the code . I realy watch full of your video. andnow inee then code but I canr pay for this because im from iran what should I do?
@MilanJovanovicTech
@MilanJovanovicTech Жыл бұрын
I'm not sure what we can do in that case. I think Patreon should support local currencies also, as long as you have a valid bank card.
@ravindranathwi
@ravindranathwi 2 жыл бұрын
Thanks for the video got a question whats the harm in putting interface over these entities. Other than multiple possible implementations. Because entities take out the testability can't really substitute or mock one of these for testing. How would you test when entity grow it becomes painful
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Why would you ever want to mock an entity?
@ravindranathwi
@ravindranathwi 2 жыл бұрын
@@MilanJovanovicTech Example I have OrderProcessHandler which takes an orderRecoverRequest. Now behaviour of the handler is. it should first load order then it should run order through a rule engine if order is valid then it should update status and send then email. Now without interface over entity you would have to create the entity in valid state run the rules engine that will raise all events and then only you can check email sent or not. So that valid state arrange is hard to setup. In interface over entity scenario I would just AutoData ask the mock factory to give me an intance and mock the other events which states that rules passed then check sendEmail is called.
@ravindranathwi
@ravindranathwi 2 жыл бұрын
@@MilanJovanovicTech also that enables whether entity method has been called from handler testing. Appreciate your input on this
@bmassioui
@bmassioui 2 жыл бұрын
Entities vs aggregates in a phrase.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Which is cooler?
@МихаилСтепанов-л3х
@МихаилСтепанов-л3х 2 жыл бұрын
You create 2 Equals. why not Equals( obj ) => Equals( obj as Entity )? No code duplicates. You check GetType == GetType and obj is Entity. @this is child of Entity. obj has equal type. so obj is Entity. So half of your code is garbage. ==: if first is null and second is null => null == null => true. but your code returns false. 1 small class full of thrash. Good job boy.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
Thanks!
@ramakrishna-ms7ly
@ramakrishna-ms7ly 4 ай бұрын
use light screen your tool in black mode and video is not clear
@MilanJovanovicTech
@MilanJovanovicTech 4 ай бұрын
Thanks
@ahmedameen2
@ahmedameen2 10 ай бұрын
Try to focus more on concept rather than code
@MilanJovanovicTech
@MilanJovanovicTech 10 ай бұрын
Dry
@anomalii7720
@anomalii7720 2 жыл бұрын
Why????? Hi, do you want to be a programmer? I will make it as hard as possible for you okay? Why? I don't know, that's just the way I am.
@MilanJovanovicTech
@MilanJovanovicTech 2 жыл бұрын
How would you solve this? 😁
How to Use Value Objects to Solve Primitive Obsession
13:54
Milan Jovanović
Рет қаралды 47 М.
Modeling a Domain With Domain-Driven Design From Scratch | DDD
19:10
Milan Jovanović
Рет қаралды 93 М.
Кто круче, как думаешь?
00:44
МЯТНАЯ ФАНТА
Рет қаралды 6 МЛН
Увеличили моцареллу для @Lorenzo.bagnati
00:48
Кушать Хочу
Рет қаралды 9 МЛН
Don't underestimate anyone
00:47
奇軒Tricking
Рет қаралды 25 МЛН
Domain Validation With .NET | Clean Architecture, DDD, .NET 6
12:31
Milan Jovanović
Рет қаралды 61 М.
Domain-Driven Design: The Last Explanation You'll Ever Need
21:05
Software Developer Diaries
Рет қаралды 11 М.
How To Use Domain-Driven Design In Clean Architecture
30:27
Milan Jovanović
Рет қаралды 112 М.
Mapping Domain-Driven Design Concepts To The Database With EF Core
18:06
Milan Jovanović
Рет қаралды 54 М.
Using Domain Events To Build A Decoupled System The Scales
14:02
Milan Jovanović
Рет қаралды 26 М.
Transactional Outbox Pattern | Clean Architecture, .NET 6
20:42
Milan Jovanović
Рет қаралды 62 М.
The Beginner's Guide to Clean Architecture
13:19
Milan Jovanović
Рет қаралды 31 М.
Clean Architecture With .NET 6 And CQRS - Project Setup
12:40
Milan Jovanović
Рет қаралды 242 М.
LED Christmas lights which don't hurt the eyes: it finally happened!
24:51
Technology Connections
Рет қаралды 13 М.
Why is Python 150X slower than C?
10:45
Mehul - Codedamn
Рет қаралды 31 М.
Кто круче, как думаешь?
00:44
МЯТНАЯ ФАНТА
Рет қаралды 6 МЛН