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

แชร์
ฝัง
  • เผยแพร่เมื่อ 9 พ.ย. 2024

ความคิดเห็น • 131

  • @MilanJovanovicTech
    @MilanJovanovicTech  2 ปีที่แล้ว +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 ปีที่แล้ว +31

    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 ปีที่แล้ว +9

      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 ปีที่แล้ว +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 ปีที่แล้ว +1

      @@flobuilds Anything that would benefit you in particular?

    • @flobuilds
      @flobuilds 2 ปีที่แล้ว +3

      @@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 ปีที่แล้ว +1

      @@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 ปีที่แล้ว +4

    Your monolog with these is excellent and demonstrates a masterful command of both English and the rest of this stuff.

  • @chrismingay6005
    @chrismingay6005 2 ปีที่แล้ว +8

    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

  • @kinggrizzly13
    @kinggrizzly13 2 ปีที่แล้ว +1

    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 ปีที่แล้ว +1

      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

  • @armanbecirovic2238
    @armanbecirovic2238 3 หลายเดือนก่อน +1

    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! 👏💪

  • @sushilb7994
    @sushilb7994 2 ปีที่แล้ว +4

    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 😊

  • @Eamo-21
    @Eamo-21 2 ปีที่แล้ว +1

    Awesome Milan! I see you on Twitter often but not TH-cam

    • @MilanJovanovicTech
      @MilanJovanovicTech  2 ปีที่แล้ว

      Hopefully the algo starts showing me some love 😁

  • @tidianediallo6199
    @tidianediallo6199 2 ปีที่แล้ว +3

    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 ปีที่แล้ว +1

      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..

  • @nickolaki
    @nickolaki 2 ปีที่แล้ว +1

    You cheeky boy putting this out today rather than tomorrow. 😉Great job Milan!

  • @modernkennnern
    @modernkennnern ปีที่แล้ว +2

    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.

  • @anthonytrad
    @anthonytrad 2 ปีที่แล้ว +4

    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.

  • @ugochukwuumerie6378
    @ugochukwuumerie6378 2 ปีที่แล้ว +1

    Awesome! Keep 'em coming. I see people using like an aggregate root to define the entity id

    • @MilanJovanovicTech
      @MilanJovanovicTech  2 ปีที่แล้ว +1

      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

  • @andergarcia1115
    @andergarcia1115 3 หลายเดือนก่อน

    I hope to be like you one day. Thanks for being an inspiration

  • @tanvirarjel
    @tanvirarjel 2 ปีที่แล้ว +2

    Good work! MIlan, Continue please! However, I have a question. What is your thought process behind naming the folder 'Primitives'?

    • @MilanJovanovicTech
      @MilanJovanovicTech  2 ปีที่แล้ว +1

      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!

  • @paulbarton2280
    @paulbarton2280 2 ปีที่แล้ว +3

    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 ปีที่แล้ว +1

      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.

  • @huynhtriet444
    @huynhtriet444 ปีที่แล้ว +1

    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  ปีที่แล้ว +2

      You'd have to cast it to an object, so that's one downside, otherwise it's possible

  • @ipelengmekgwe834
    @ipelengmekgwe834 6 หลายเดือนก่อน

    Your videos are so informative, thank you!

  • @Yosso117
    @Yosso117 ปีที่แล้ว +1

    Братан, хорош, давай, давай, вперёд! Контент в кайф, можно ещё? Вообще красавчик! Можно вот этого вот почаще?

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว

      More about DDD or more about Entities?

    • @LilPozzer
      @LilPozzer 5 หลายเดือนก่อน

      extreme code

  • @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 หลายเดือนก่อน +1

      I made a separate video on that

    • @9_vko
      @9_vko 2 หลายเดือนก่อน

      @@MilanJovanovicTech Awesome! 😎

  • @MrKlyushin
    @MrKlyushin ปีที่แล้ว +1

    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  ปีที่แล้ว +1

      If you need inheritance, of course

    • @MrKlyushin
      @MrKlyushin ปีที่แล้ว

      @@MilanJovanovicTech thx! 👍

  • @aseneda
    @aseneda 2 ปีที่แล้ว +1

    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 ปีที่แล้ว +2

      Next video will be Domain validation.
      Followed by Value Object, Aggregates, Domain Events... 😁

  • @garethcraig8902
    @garethcraig8902 5 หลายเดือนก่อน

    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  5 หลายเดือนก่อน

      You probably don't generate those values client-side?

  • @ujuzitek301
    @ujuzitek301 ปีที่แล้ว +1

    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

  • @pigrebanto
    @pigrebanto 10 หลายเดือนก่อน

    Good stuff! Why you have 2x Equals methods in the Entity class? isn't the one on the Entity (Equatable interface) enough?

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 หลายเดือนก่อน +1

      One is object.Equals and one is IEquatable.Equals

  • @سهیلداودی-ص1ف
    @سهیلداودی-ص1ف 2 ปีที่แล้ว +1

    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?

  • @vertikalniserklaz8694
    @vertikalniserklaz8694 ปีที่แล้ว +1

    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  ปีที่แล้ว +1

      There's a video on user registration and validating duplicate emails that I'm sure you'll enjoy

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว +1

      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 th-cam.com/video/eC7GMGIR4Gw/w-d-xo.html

  • @MarincaGheorghe
    @MarincaGheorghe 16 วันที่ผ่านมา

    A question. Why would you need to compare entities in your domain: collision or what? Who would need to use equality on these ?

  • @jimkoro664
    @jimkoro664 2 ปีที่แล้ว +1

    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 ปีที่แล้ว +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 ปีที่แล้ว +1

      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.

  • @iliyan-kulishev
    @iliyan-kulishev 2 ปีที่แล้ว +1

    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

    thanks

  • @dhanushshetty7840
    @dhanushshetty7840 2 ปีที่แล้ว +1

    Is there going to be more refactoring so that we can execute moq frameworks to unit test?

  • @zheniachubarov3384
    @zheniachubarov3384 9 หลายเดือนก่อน +1

    Does EF Supports init modifier?

  • @sinafallahpour2626
    @sinafallahpour2626 ปีที่แล้ว +1

    very good video

  • @dandoescode
    @dandoescode ปีที่แล้ว +1

    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

  • @afermeherremova5672
    @afermeherremova5672 ปีที่แล้ว +1

    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  ปีที่แล้ว +1

      You can - but beware of how you will use that Entity in any generic context

  • @bohdankatrychenko2479
    @bohdankatrychenko2479 ปีที่แล้ว +1

    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

  • @imaynedlog9628
    @imaynedlog9628 ปีที่แล้ว +1

    Why do you need init in Entity class? Because we set ID using constructor anyway, we just need readonly ID property, don't we?

  • @mahmoudalballah3387
    @mahmoudalballah3387 ปีที่แล้ว

    Awesome!

  • @nikolaignjatovic6788
    @nikolaignjatovic6788 2 ปีที่แล้ว +1

    Nice video. Why 41?

    • @MilanJovanovicTech
      @MilanJovanovicTech  2 ปีที่แล้ว +4

      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?

  • @microtech2448
    @microtech2448 ปีที่แล้ว +1

    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  ปีที่แล้ว +1

      Of course, just more boilerplate

    • @microtech2448
      @microtech2448 ปีที่แล้ว

      ​@@MilanJovanovicTechcan you post something on this as community post?

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว +1

      @@microtech2448 Sure 😁

    • @microtech2448
      @microtech2448 ปีที่แล้ว

      @@MilanJovanovicTech thanks 🙂

  • @ivandrofly
    @ivandrofly ปีที่แล้ว +1

    1:03 - Definition* of Entity

  • @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

  • @imaynedlog9628
    @imaynedlog9628 ปีที่แล้ว +1

    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)

  • @bmassioui
    @bmassioui 2 ปีที่แล้ว +1

    Entities vs aggregates in a phrase.

  • @МихаилСтепанов-л3х
    @МихаилСтепанов-л3х 2 ปีที่แล้ว +3

    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.

  • @sinafallahpour2626
    @sinafallahpour2626 ปีที่แล้ว +1

    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.

  • @ramakrishna-ms7ly
    @ramakrishna-ms7ly 4 หลายเดือนก่อน

    use light screen your tool in black mode and video is not clear

  • @ahmedameen2
    @ahmedameen2 10 หลายเดือนก่อน

    Try to focus more on concept rather than code

  • @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.