How To Persist DDD Value Objects? THIS Will Make Your Life EASIER

Ғылым және технология

When it comes to DDD, persistence is a big pain point that people discover abruptly. One of the trickiest parts is persisting DDD value objects. The main challenge with DDD value objects is that they don't have identifiers, and therefore persisting them is hacky. And you usually get a lot of EF Core exceptions until you're even able to do a migration. Not anymore! In this video we'll uncover some tips that will make persisting DDD value objects way easier.
✅ Join this channel to get source code access and other perks:
/ @codewrinkles
Contents
1. Intro: 00:00
2. Recap: aggregates and value objects: 01:44
3. First challenge: constructor 07:06
4. Challenges with private setters: 09:10
5. Biggest challenge: missing identifiers 10:17
6. Aggregates and DbSets: 11:09
7. Ef Core owned entity types FTW! 11:46
8. Evaluating the migration: 14:51
9. Persisting new aggregates: 17:12
10. Updating existing aggregates: 22:03
11. Conclusions: 26:48

Пікірлер: 37

  • @Codewrinkles
    @Codewrinkles Жыл бұрын

    I want to emphasize,, that DDD is not something that's we should aim for in each application. The full DDD approach is only useful when you have large projects with a lot of business rules and logic, when there's a business that understands that their language is part of how the application is modeled. This often translates in systems where there will be probably several teams working at the same time, separated by bounded contexts. Often, when DDD is really needed it also results in microservices, where each bounded context becomes a microservice. So, implementing DDD everywhere is for sure a NO GO. We starting on new projects, use DDD only as a last resort. That should never be the first option. Still, you can use some of the DDD principles and practices in any app IF IT MAKES SENSE. DDD != a good application. In fact, if it's deployed where it shouldn't, most probably it will result in bad apps.

  • @LE8271
    @LE82713 ай бұрын

    This is the inconvenient truth about DDD. The persistence hell. To be clear you are the only content creator who deals with updates and I fully respect that. All others (including paid trainings) does not event talk about that part as it is really tricky. Imagine a form where the user submits all changes at once. Multiple addresses, perhaps last and first name at the very same time using a single DTO in its call. That is where DDD falls apart or creates persistance very complex at least. The maintainability suffers. Today with Blazor where you do not need a DTO and you can throw in an existing object it is even trickier.

  • @diogosilva8219
    @diogosilva82198 ай бұрын

    Your content is amazing, keep it up! Greetings from Portugal! 🇵🇹

  • @kokchunng8178
    @kokchunng81789 ай бұрын

    Great video! 24:30 I have a question about the difference of params "updatedAddress" and "existingAddress" If i send a payload example to this PUT API, will "updatedAddress" and "existingAddress" hold the same value and how the address will be updated to new one? Example: { streetName : "value" streetNumber: "value" city:"value" country:"value" }

  • @jcmoore2013
    @jcmoore201311 ай бұрын

    Do you have any videos for DDD persistence, which does not use entity framework. Uses repository pattern. Trying to determine the best way to update aggregate stored in SQL for creating, updating, deleting it... There is a lot on content for entity framework, but not for repository pattern and manual calls to Sql stored proc's.

  • @gabrielverle9469
    @gabrielverle9469 Жыл бұрын

    what if i have a lot of records of Addresses? Maybe address is not a good example, but lets say i have an aggregate root "Post" that have "Comments". If my post has 50000 records, do i need to load them all just to make modifications through my aggregate?

  • @GarethDoherty1985
    @GarethDoherty1985 Жыл бұрын

    How safe/secure is this Aggregate stuff in a Multi-Tenant app where tenants share the same DB. I have read for shared DB's each Table should contain the Tenant Key to make sure there is no chance of reading another tenants data from a table. So far in Aggregates, I can only really see the Root Aggregate only having the Tenant key since it is only the Root that you will retrieve from the DB and modify etc. Same with Audit level details like Created/Modified By and Created/Modified On. Are these properties only ever on the Root? Again because you are always working with the Root and persisting the Root to the DB.

  • @flobuilds

    @flobuilds

    Жыл бұрын

    Thats a great question. I'm currently building a multi tenant application like you explained but i have all audit values and the tenant id in every table. I also don't use value Objects for persisting lists but rather sup entities with their own logic for enforcing Business rules. I would use value Objects only on owned values like the name for example. I also use an adress table which represents a sup entity. So in my opinion you should only use value objects in places where you can easily change the value with the new one when changing (eg. FirstName, LastName,...). It's just way easier to use. Hope this helps a little

  • @francisdar127
    @francisdar127 Жыл бұрын

    Great video as always! What's your take on creating separate models for the purpose of persistence? For example, there'll be an Address class for the domain with no ID and another Address class for persistence with an Id. I believe this would solve all the problems you mentioned without compromising the domain or the API projects. The persistence classes can also contain additional fields that would make sense from a persistence perspective but would not fit in the domain perspective. The downside I can see with this approach is there will be a lot more classes and mappers that would be needed.

  • @Codewrinkles

    @Codewrinkles

    Жыл бұрын

    I guess I will tackle this topic at some point. Having different write and read models and even persistence models is something that in some cases might be even needed when everything gets to complex. However, generally when I'm thinking in DDD terms, I like to go with the idea of an aggregate being a boundary of consistency all the way to being a transactional boundary. Which implies that (for writes at least) the aggregates should also have a DbSet. For reading data it's true, that's not necessarily needed.

  • @stijnnel4798

    @stijnnel4798

    Жыл бұрын

    Why would you, even in a domain with just a couple of aggregates & value objects. You would be spending 80 percent of time to implement a new feature maintaining the mapping and possibly fixing tests.

  • @uzayrsyed6293

    @uzayrsyed6293

    Жыл бұрын

    How about embedding the value object in the table rather than having a separate table?

  • @tarikpalic6304
    @tarikpalic6304 Жыл бұрын

    What happens if the Customer entity needs another value object? For example Status, where the possible properties can be: Name and Comment. So a Status can be like: Name: "INACTIVE", Comment: "Customer is a cheat".... If this is persisted together with the Customer entity, that is fine. But if we have a requirement to show a list of all statuses in some UI control, how do we obtain that data? Would it be OK in this case to store the value object in a dedicated table?

  • @Codewrinkles

    @Codewrinkles

    Жыл бұрын

    You can configure to store 1:1 value objects also in a different table via the FluentAPI. Still, that probably doesn't answer the question. showing statuses in the UI is not something that concerns the domain logic. This sounds to me like static data that can be seeded in a dedicated table. But you would use read models to get it, not domain objects.

  • @adahadapato
    @adahadapato6 ай бұрын

    thank you for this video, please how do use this Entity base class on entities with different Key names like candidatNumber, Code etc. it works If the name is Id. thank you

  • @ryoman76
    @ryoman76 Жыл бұрын

    Great! With this video you have clarified many doubts for me. I was left with a curiosity if I had a many-to-many relationship between an aggregate and an object of value. How do I go about the insert edit and delete operations? Thank you

  • @Codewrinkles

    @Codewrinkles

    Жыл бұрын

    That's just based on personal experience, so don't take it as a "best practice". I have observed that if you model your domain correctly you usually don't have many-to-many relationships between aggregates and value objects. That kind of defeats the purpose of value objects. So for me this would be a red flag that something in my modeling was not correct. But if you are still in this scenario that's the point where we need to make concessions and give value objects identifiers with the sole purpose of persistence. If you want to be a purist you could also create dedicated persistence model that are different from your domain models. In that case you can persist data any way you want. And in the repositories you would then get the persistence models from the db and create the domain model by yourself. Another approach would be to consider using JSON objects instead of full fledged many-to-many relationships. EF Core fully supports this starting EF 7.

  • @ryoman76

    @ryoman76

    Жыл бұрын

    @@Codewrinkles tnk

  • @LE8271

    @LE8271

    3 ай бұрын

    You cannot have many-to-many relationship. Having many-to-many would mean at least two aggregates both depending on the same object value from consistency point of view. That would mean that chaging one can cause inconsistency in the other. What you talk about there should be three aggregates each having eventual consistency and you should raise domain event to ensure full consistency in a later stage. Aggregate either owns the value (1-1) or refers another aggregate using the others ID.

  • @simonecambursano9266
    @simonecambursano9266 Жыл бұрын

    What is instead the right approach when it comes to persist entities related to an aggregate? Let's say an aggregate has one to many relation with some entity. Is it ok in this case to "pollute" the entity model with the foreign key of the aggregate? Also in this case I assume it is better to use hasMany rather than ownsMany in the ef configuration. Thanks again for your great videos. They are super helpful.

  • @Codewrinkles

    @Codewrinkles

    Жыл бұрын

    The relationship should be configured via fluent API in configuration classes. And yes, in that case it would be configured with HasMany().

  • @simonecambursano9266

    @simonecambursano9266

    Жыл бұрын

    @@Codewrinkles one more thing when it comes to persisting entities which are not aggregates. Does in this case a DbSet need to be defined? Or that applies only to aggregates?

  • @Codewrinkles

    @Codewrinkles

    Жыл бұрын

    When you go for DDD, everything is an aggregate. You don't have standalone entities. It's also true, on the other hand, that you might have an aggregate that's comprised of only one entity. In that case, of course it should have the DBSet. But this is more like an edge case.

  • @Codewrinkles

    @Codewrinkles

    Жыл бұрын

    I want to emphasize, though, that DDD is not something that's we should aim for in each application. The full DDD approach is only useful when you have large projects with a lot of business rules and logic, when there's a business that understands that their language is part of how the application is modeled. This often translates in systems where there will be probably several teams working at the same time, separated by bounded contexts. Often, when DDD is really needed it also results in microservices, where each bounded context becomes a microservice. So, implementing DDD everywhere is for sure a NO GO. We starting on new projects, use DDD only as a last resort. That should never be the first option. Still, you can use some of the DDD principles and practices in any app IF IT MAKES SENSE. DDD != a good application. In fact, if it's deployed where it shouldn't, most probably it will result in bad apps.

  • @simonecambursano9266

    @simonecambursano9266

    Жыл бұрын

    Thanks for the explanation. Although what I meant here, is the case when we have for example an aggregate root which has a collection of entities as property (same as in the example but instead of value objects we have collection of entities). How would you approach the persistence of this collection of entities? Is a DbSet necessary in this case?

  • @kasozivincent8685
    @kasozivincent868510 ай бұрын

    Hahahaha this is my current situation. I built my entities using functional concepts and am now struggling to persisting them

  • @mohamedhosman
    @mohamedhosman9 ай бұрын

    you don't need to have you face on the screen all the time, sometimes it hides important parts of the sceen.

  • @fadidib8516
    @fadidib8516 Жыл бұрын

    LOL all these ads on each word

  • @Codewrinkles

    @Codewrinkles

    Жыл бұрын

    What are you talking about?

  • @fadidib8516

    @fadidib8516

    Жыл бұрын

    @@Codewrinkles u just molded ur domains with the mold stuff, and ur domain are amazing with the VR thing etc

Келесі