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.
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.
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.
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
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.
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.
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.
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" }
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.
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?
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?
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.
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
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.
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.
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 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?
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.
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.
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?
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
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.
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.
Your content is amazing, keep it up! Greetings from Portugal! 🇵🇹
you don't need to have you face on the screen all the time, sometimes it hides important parts of the sceen.
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.
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
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.
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.
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.
How about embedding the value object in the table rather than having a separate table?
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"
}
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.
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?
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?
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.
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
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.
@@Codewrinkles tnk
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.
Hahahaha this is my current situation. I built my entities using functional concepts and am now struggling to persisting them
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.
The relationship should be configured via fluent API in configuration classes. And yes, in that case it would be configured with HasMany().
@@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?
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.
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.
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?
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
LOL all these ads on each word
What are you talking about?
@@Codewrinkles u just molded ur domains with the mold stuff, and ur domain are amazing with the VR thing etc