Get the source code for this video for FREE → the-dotnet-weekly.ck.page/domain-modeling Want to master Clean Architecture? Go here: bit.ly/3PupkOJ Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt
@MilanJovanovicTech i cant understand, can u please explain in plain english how u can - what exactly means 'Domain'? if possible with example. Thank you.
Such a smooth introduction into some of the tactical DDD concepts :) Love usage of the records part and the fact that you started fresh with a simple domain model! Stay awesome Milan!
I do Business Intelligence dimensional modeling and it's cool how similar it is to the domain-driven design you are teaching here. When we have shared objects across domains when we call those "conformed dimensions". We put them in a "shared" folder as you mentioned, but then we produce references to them in each domain so that, as for as the domain is concerned, it exists within its folder. Of course, I am comparing apples to oranges since these are just datamarts and not applications but it's cool to see similar concepts. I could almost envision myself using something similar to this for building a data warehouse in C#, but the output would probably need to be columnar parquet files and I'm not sure I understand how you would do large updates across records in this design. I subscribed and will definitely watch more.
Creating a folder per entity is not organising the model around features, it's organising it around entities. Features are about functionality, i.e. behaviour. You started from what is essentially a normalized database schema and created a 1 to 1 correspondance with classes representing entities. Use cases, functionality, behaviours were presented as an afterthought
I sometimes use feature folder/aggregate folder interchangeably. The main idea being to promote this type of folder structure as opposed to a technical one such as Entities/[all the domain classes inside]
The records are not completely safe with the private constructor, because of the copy constructor they have, allowing the 'with' syntax. So you can create an invalid SKU for example, from a valid one.
Ah, but does that change *the existing* record instance, or creates a new one? 😁 Agreed, you can bypass it using the *with* expression, but do you even want to bother with that _hack_?
@@MilanJovanovicTech It creates a new instance. Just pointing out that records have some caveats. It would be strange for a developer hacking his own code
Great video as always. Are you planning to create a series or course like creating an application from scratch, adding more functionality, and showing the best practices? Something like the first DDD series, but recorded from 0, without code written with the camera off. Feel free to interpret this as a suggestion :D. Love from Poland
Hi, Milan. I'm trying to repeat your project with my own additions and wanted to clarify some points: 1. Why did you change the LineItems type from HashSet to List in one of the videos, if you wanted unique values in it. 2. How many Orders can one user have? Does the Order entity serve as a kind of product cart? 3. Does AutoMapper conflict with DDD principles?
Hello Milan I love your videos. DDD ones are my favorite. I would love to see a video where you explain how to decide which entities should be aggregate roots and which Entities they control. I will conjure up an example based on this video. We have Customer | Order | LineItem We could split it into 2 aggregate roots first beeing Customer alone The second one would be Order and it would control LineItem which means that you could only create it using methods exposed in Customer Why not set only Customer class as an aggregate root? It would control Order and LineItem. Or maybe it would control Order and Order would control LineItem? What are the rules of deciding the boundries between aggregate roots? Should we keep aggregates as small as possible?
Ask this question: Can the Order exist without the customer? The Customer has to create the Order, yes. But someone else can also create the Order on behalf of the Customer. And even if we delete the Customer from our system, the Order should remain as a historical fact.
Great DDD video Milan! Will you soon pierce the veil of persistence ignorance and do a video on how to map this domain model to an ORM like EF Core? I’m very interested in how you treat the Value Object side of things. 🙌
I have two question which is the best practise : 1- have the IRepository in the domain or the application layer? 2- When validation we have to return a questom Result type instead of thrown the error, so we need to put the custom response to the domain layer also? thank you so much for you videos and your help
Great video ! ...but I have a quick question. Money becomes a shared concept and you stated it might be good to create a shared folder, then you used the Customer in your Order without any need to move it in a shared folder or to create a Customer in your Order folder. Why ? And what would be your contexts boundaries ? I felt like each "folder" could be considered a context and needed to be independant. Might be in a newer video that I missed, so feel free to push me in this direction. :D
We're still inside a single domain, so it's a bit difficult to see everything. I think it'll make more sense when I move into a Modular Monolith architecture.
Thanks for the content. I have a question about the utility of OrderId in LineItem. I understand very well for the database schema (infrastructure) that this field is needed to retrieve the lines, but in the domain if Order is an aggregate and LineItem is managed by Order and don't need OrderId. I have seen another content about this subject where the author removes the aggregate id from the entity which is incorporated in the aggregate, that why I wonder that.
Agreed, from a pure Domain model perspective it's not required. But I do add it since I like to be practical, and also solve some persistence concerns ahead of time.
nice vid, one question, we introduced validation in our domain, if the rules of creating valid domains becomes bigger and bigger, where should we put them, and how to utilize them in the domain (constructor, using it staticly, etc) ?
yes but i mean simple null checking is ok in the domain record/class (correct me if i am wrong), but if i have a big and complex validation it should be in the application project, but i want to make sure that the record/class instance object is not created unless it is considered valid, so in this case what should we do?@@MilanJovanovicTech
Great job. I hope you will continue these videos. Have you ever planed to show us a bad part of DDD? I mean a communication with database. How to configure entities for db and how to handle situations, when the amount of data grows and your entities contain collections of other entities. Is lazy loading a good or a bad practice?
Hello @Milan Thanks for the video: I like it! I have two questions (basic questions), if I can: 1/ Why did you choose to create a record Money instead of a class? 2/ Why did you choose to make Create method inside Order class as static instead of non-static?
1) With a record I get structural equality, which is a quality I want for my value objects 2) What would call the Create method if it wasn't static? I'd need an order instance - but then what's the point of having a Create method.
Thank you for your videos. one quick question, why not use constructor to validate the creation of object instead of creating factory method. factory method can be useful if the object creating is complex.
If I have Product, Specification, and SpecificationType aggregate roots, can I refer directly to the Specification instead of just id? Or do I need to get the specifications for each product every time I get the product page? Or maybe should I use separate read/write models?
We can make ProductId a value object too, and pass it to Add() method instead of whole Order object. upd: oh, sorry, you already make video about strongly typed Id after this video :)
@MilanJovanovicTech I was just thinking from high-performance application pov where many orders are getting created simultaneously and while creating order object via factory if we pass customer info, is it possible that other customer info gets populated rather actual customer info.
Hi Milan. Do you always have to make a Static Factory Method just to get set entity's properties? Or constructor, whatever. And you didn't do that for Customer entity. Why?
Hey! What if I define ProductId not just like GUID but as you've done it in some other videos where you've created separate file ProductId with a record (Guid Value). Now I can't just reference this type in LineItem because it comes from another aggregate (Product). What is a workaround here? Is it to create very same ProductId record in Order folder?
Even better if id's were strongly typed like: public record ProductId(Guid Value); Don't do that and you receive a contraption like this LineItem constructor that is asking for troubles. I'm just assuming it's for the sake of keeping the video reasonably short. Wouldn't hurt to at least mention that pattern, though. Other than that great tutorial, thanks!
I'm wondering if LineItem should be an entity? I don't think it needs an Id when it can use OrderId and productId to identify it. It does need its own table, so does that mean it's entity by default?
What happens when there are many line items? So that there are performance issues when loading all of them into memory. If you make it into an entity, you can solve that problem by just loading that one entity.
At 0:40 you are describing the domain model, what exactly you are referring to? Are you pointing to entities, aggregate roots, and value objects or there is something else that belongs to the domain model?
With Domain model I mean the conceptual representation of problem domain in the diagram. Entities/Aggregates/Value objects are just tactical patterns to represent the Domain model in the code and enforce the invariants.
Great explanation and Great video. I have tried it. It works also have tables with correct data but .... When I read from table _context.Orders.Include("ListItems").ToList(); It fails to load. If I use it without include then it works but don't have ListItems data _context.Order.ToList();
@@MilanJovanovicTech Check out Khorikov’s article about the suitability of records as value objects. He puts forward a decent argument. I came across it a while back, which was enough for me to be deterred from using them with EF core, at least for the time being. Also, value objects aside, Microsoft documentation says that EF doesn't support updating with immutable entity types, which is not a total show stopper of course but does make few alarm bells ringing when you consider using them with EF in general. If you found a nice and neat way of incorporating them as value objects - I’m really looking forward to your video on Tuesday 👍
I'm on the model screen and I would like to see it expanded to customer has price list and product has different price per price list :) (sorry if something is later in the video about it :D )
@@MilanJovanovicTech you did not. However the concept I've mentioned in one hand seems to be fairly simple on the other hand it brings a lot of complexity. For example, customer can be moved from one price list to another between orders
I did ask you this a few months back and you gave me an answer I tried it I put together something that works but I wasn't sure it it still conforms to DDD and best practices. 1. Can we use interfaces in DDD Domain Modelling(if Possible is it advisable)? The reason why I was asking is that I was trying to find the best way to model the data below. The backstory is that in my App I need to communicate with Different renderers one renderer I am sending data over TCP and in the other I am writing data to a File. Is it good practice to have different types of Objects In a collection in Json? Or would be better to Split the Data of One Json with the ID and Type I would then make another trip to the database/API using the Id from the first json so that I can get all the 'rendererDatas'. If the below Json is up to standard what's the best way to model this in DDD? [ { "id": "859b6427-a84a-4ac7-1234-21864cf46c86", "name": "string", "description": "string", "rendererDatas": [ { "id": "ea0e7e36-ffe0-6543-83f0-23d46968b2aa", "name": "string", "DataType": "Viz", "description": "string", "IPAddress": "123.123.123", "rendererAttributes": [{"FirstName": "John", "Number": "8"}] }, { "id": "ea0e7e36-6543-6543-83f0-23d46968b2aa", "name": "string", "DataType": "Ventuz", "description": "string", "FilePath": "C:\Data", "Payload": "Json payload with Firstname and Number" } ] } ]
The UI that uses this API data has a List of more than object types but has the same base/parent. The User interface needs to do CRUD on the list, so one bit I was not sure about is how should the information be present in the API. So should GetItems() have all the different object types in one list in the response data? Or should it be multiple lists and it's up to the user to manage the data(fetching all the list and merging it in one)?
Why do we use the Create method? Why don't we use a constructor for this? After all, you can define all the checks during creation in the public constructor. What is the point of Create?
In this example, would modifying the price of a Product entity be restricted to an Order aggregate? How would you update a Product that did not belong to an Order?
one more thing please I cannot understand actually what is the difference when we create a recordcalled Money that has two props : Curreny and amount And of simply adding two Columns inside the table called : Currency and Amount ?
Hey Milan. What is the most effective way to change dependent class fields from other classes in the DDD approach?Just create methods inside the class to add/update/delete for each field? Do I really have to write a cqrs commands for every change to this entity? Let's say, in addition to the usual fields in class "A", there are the following related to other classes that i want to change: public IReadOnlyList? Cuisines => _cuisines?.ToList(); private readonly List _cuisines = new(); public IReadOnlyList? Reviews => _reviews?.ToList(); private readonly List _reviews = new(); public IReadOnlyList? Features => _features?.ToList(); private readonly List _features = new(); public IReadOnlyList? WorkSchedules => _workSchedules?.ToList(); private readonly List _workSchedules = new();
@@MilanJovanovicTech Yeah...any suggestions then?🙄 I mean, In my subject area, there is a Catering class that depends on the tables of Features, Cuisines, Reviews and Work Schedules, as written above. Splitting the Catering class into smaller ones does not seem optimal to me.
Hi One question. How does it goes with EF core. I mean if we have associations with different class. EF core will treat them as separate tables, which could go wrong for example Price record. Please share insights regarding this. thanks
@@MilanJovanovicTechI really appreciate your quick response.... I see GUID are not sequenced does it benefit us really If our Database is not distributed.
Wow, thank you very much Daniel! 😊 I don't often get 'super thanks' so I'll remember this one for a while. Anything I can do for you to be helpful? Maybe you have a video suggestion?
You say from scratch - then jump straight into a project with a domain set up with no explanation of how you got there....for those of us not familiar with VS that first step would have been nice to see.
@@MilanJovanovicTech Well, I find it confusing for a beginner to understand the idea behind DDD if you go straight and show source code. In reality, DDD is very unspecific, abstract and behind source code. Especially, when talking about Bounded Contexts, Context Mapping (OHS, ACL etc.) which is actually a graphical process, shown by unified diagrams, which both, stakeholders and developers, can understand.
Get the source code for this video for FREE → the-dotnet-weekly.ck.page/domain-modeling
Want to master Clean Architecture? Go here: bit.ly/3PupkOJ
Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt
@MilanJovanovicTech i cant understand, can u please explain in plain english how u can - what exactly means 'Domain'? if possible with example. Thank you.
Love the approach of doing these from scratch, I'd like to see more of this!
Thanks, I'll try to balance this out in the future and include more "from scratch" videos
we support you continue >>>>>
I need the support. Thank you!
Such a smooth introduction into some of the tactical DDD concepts :) Love usage of the records part and the fact that you started fresh with a simple domain model! Stay awesome Milan!
I was against records for a while, but now I realize they're perfectly fine
Thanks Milan, can't get enough of your videos.
What a compliment 😁
I do Business Intelligence dimensional modeling and it's cool how similar it is to the domain-driven design you are teaching here. When we have shared objects across domains when we call those "conformed dimensions". We put them in a "shared" folder as you mentioned, but then we produce references to them in each domain so that, as for as the domain is concerned, it exists within its folder. Of course, I am comparing apples to oranges since these are just datamarts and not applications but it's cool to see similar concepts. I could almost envision myself using something similar to this for building a data warehouse in C#, but the output would probably need to be columnar parquet files and I'm not sure I understand how you would do large updates across records in this design. I subscribed and will definitely watch more.
Huh, now you've inspired me to learn more about BIDM (I made up this acronym) 😁
Creating a folder per entity is not organising the model around features, it's organising it around entities. Features are about functionality, i.e. behaviour. You started from what is essentially a normalized database schema and created a 1 to 1 correspondance with classes representing entities. Use cases, functionality, behaviours were presented as an afterthought
I sometimes use feature folder/aggregate folder interchangeably. The main idea being to promote this type of folder structure as opposed to a technical one such as Entities/[all the domain classes inside]
Great explanation and the fact that you start from scratch is very helpful!
Looks like people enjoy "from scratch" videos. I'm tempted to make more of these
Thank @millan for this awesome exercise.
Glad you liked it!
Great video. And really like that you point what is difference between Entity and AggregateRoot.
Thank you, I'm glad it was clear :)
The records are not completely safe with the private constructor, because of the copy constructor they have, allowing the 'with' syntax. So you can create an invalid SKU for example, from a valid one.
Ah, but does that change *the existing* record instance, or creates a new one? 😁
Agreed, you can bypass it using the *with* expression, but do you even want to bother with that _hack_?
@@MilanJovanovicTech It creates a new instance. Just pointing out that records have some caveats. It would be strange for a developer hacking his own code
Great video as always. Are you planning to create a series or course like creating an application from scratch, adding more functionality, and showing the best practices? Something like the first DDD series, but recorded from 0, without code written with the camera off. Feel free to interpret this as a suggestion :D. Love from Poland
Yes, something like that. I'll try to either not write code off-screen, or use existing libraries
very clear thank you for the continuous contribution
You are very welcome. I prepared a few more in the coming days :)
@@MilanJovanovicTech looking forward to it am building my own DDD architecture following your tips
Hi, Milan. I'm trying to repeat your project with my own additions and wanted to clarify some points:
1. Why did you change the LineItems type from HashSet to List in one of the videos, if you wanted unique values in it.
2. How many Orders can one user have? Does the Order entity serve as a kind of product cart?
3. Does AutoMapper conflict with DDD principles?
1 - No particular reason
2 - Many orders. It's the purchase/sale
3 - Not necessarily, but I don't use mapping libraries
Very good. Very clear. Thank you.
I prepared a few more on DDD, and we'll see where I take it from there 😁
Great from scratch to advance 😍
I think we need more videos like that. Do you agree?
@@MilanJovanovicTech Definitely🙏
@@MilanJovanovicTech yes ❤️
Hello Milan I love your videos. DDD ones are my favorite.
I would love to see a video where you explain how to decide which entities should be aggregate roots and which Entities they control.
I will conjure up an example based on this video.
We have Customer | Order | LineItem
We could split it into 2 aggregate roots first beeing Customer alone
The second one would be Order and it would control LineItem which means that you could only create it using methods exposed in Customer
Why not set only Customer class as an aggregate root? It would control Order and LineItem. Or maybe it would control Order and Order would control LineItem?
What are the rules of deciding the boundries between aggregate roots?
Should we keep aggregates as small as possible?
Ask this question: Can the Order exist without the customer?
The Customer has to create the Order, yes.
But someone else can also create the Order on behalf of the Customer.
And even if we delete the Customer from our system, the Order should remain as a historical fact.
Great DDD video Milan! Will you soon pierce the veil of persistence ignorance and do a video on how to map this domain model to an ORM like EF Core? I’m very interested in how you treat the Value Object side of things. 🙌
Owow! I should have looked deeper before posting! Tysm! 🎉ruclips.net/video/IlXnIe6p_Uk/видео.html
I see you found the answer 😁
Thank you Milan, l like your explanation
You are welcome!
I have two question
which is the best practise :
1- have the IRepository in the domain or the application layer?
2- When validation we have to return a questom Result type instead of thrown the error, so we need to put the custom response to the domain layer also?
thank you so much for you videos and your help
1) You need to decide what approach you're taking, I did a video about it a week or two ago
2) Or you can use some sort of generic Result type
Liked, waiting for the next one😊
More to come!
Very clearly explained
Thanks!
Great video ! ...but I have a quick question. Money becomes a shared concept and you stated it might be good to create a shared folder, then you used the Customer in your Order without any need to move it in a shared folder or to create a Customer in your Order folder. Why ? And what would be your contexts boundaries ? I felt like each "folder" could be considered a context and needed to be independant.
Might be in a newer video that I missed, so feel free to push me in this direction.
:D
We're still inside a single domain, so it's a bit difficult to see everything. I think it'll make more sense when I move into a Modular Monolith architecture.
Hi Milan, Question, why did you add a concrtuctor in the order page ? Or constructors are mandatory in all the classes you create
I usually add the constructors directlt
Thanks for the content. I have a question about the utility of OrderId in LineItem. I understand very well for the database schema (infrastructure) that this field is needed to retrieve the lines, but in the domain if Order is an aggregate and LineItem is managed by Order and don't need OrderId. I have seen another content about this subject where the author removes the aggregate id from the entity which is incorporated in the aggregate, that why I wonder that.
Agreed, from a pure Domain model perspective it's not required. But I do add it since I like to be practical, and also solve some persistence concerns ahead of time.
@@MilanJovanovicTech I see. Thank you for your answer.
Nice! Waiting for next
Will upload soon
nice vid, one question, we introduced validation in our domain, if the rules of creating valid domains becomes bigger and bigger, where should we put them, and how to utilize them in the domain (constructor, using it staticly, etc) ?
Do you make a distinction between domain rules and application/data-integrity rules?
yes but i mean simple null checking is ok in the domain record/class (correct me if i am wrong), but if i have a big and complex validation it should be in the application project, but i want to make sure that the record/class instance object is not created unless it is considered valid, so in this case what should we do?@@MilanJovanovicTech
Great job. I hope you will continue these videos. Have you ever planed to show us a bad part of DDD? I mean a communication with database. How to configure entities for db and how to handle situations, when the amount of data grows and your entities contain collections of other entities.
Is lazy loading a good or a bad practice?
You have a great understandable accent. Where are you from?
Serbia :)
And yes, I actually have a few video recorded
- Strongly Typed IDs
- Anemic Domain Model
- EF + DDD Mapping
Looks like I hit the right topics? 😁
@@MilanJovanovicTech Yeah, Right. We are waiting new series.
Hello @Milan
Thanks for the video: I like it!
I have two questions (basic questions), if I can:
1/ Why did you choose to create a record Money instead of a class?
2/ Why did you choose to make Create method inside Order class as static instead of non-static?
1) With a record I get structural equality, which is a quality I want for my value objects
2) What would call the Create method if it wasn't static?
I'd need an order instance - but then what's the point of having a Create method.
@@MilanJovanovicTech sorry for the second question: it seems two stupid 😅
Thank you for your videos. one quick question, why not use constructor to validate the creation of object instead of creating factory method. factory method can be useful if the object creating is complex.
I prefer not throwing exceptions if creation fails - which you can't avoid with constructors
Nice intro to ddd modeling, just add strongly typed ids to avoid primitive obsession and that's all :)
Did you just guess what the next video is about? 👀
Great video as always, thanks!
What program do you use to create the diagram? Looks great.
Excalidraw :)
If I have Product, Specification, and SpecificationType aggregate roots, can I refer directly to the Specification instead of just id? Or do I need to get the specifications for each product every time I get the product page? Or maybe should I use separate read/write models?
Its fine to fetch them all at once. Fewer round trips to the DB.
Thanks, from my heart!
You're welcome!
Thank you Milan!
Any time!
We can make ProductId a value object too, and pass it to Add() method instead of whole Order object.
upd: oh, sorry, you already make video about strongly typed Id after this video :)
Yup, but I'm glad you made a connection between the two videos 😁
Since static methods are not thread safe, is it a good idea to use it while creating objects.
Why would I care about that in the context of creating a Domain entity?
@MilanJovanovicTech I was just thinking from high-performance application pov where many orders are getting created simultaneously and while creating order object via factory if we pass customer info, is it possible that other customer info gets populated rather actual customer info.
Another great video, thanks a lot!)
Glad you liked it!
Hi Milan. Do you always have to make a Static Factory Method just to get set entity's properties? Or constructor, whatever. And you didn't do that for Customer entity. Why?
No, not always. Static factory is useful when I want to trigger some side effects after creating the entity.
Hey! What if I define ProductId not just like GUID but as you've done it in some other videos where you've created separate file ProductId with a record (Guid Value). Now I can't just reference this type in LineItem because it comes from another aggregate (Product). What is a workaround here? Is it to create very same ProductId record in Order folder?
The ID is still something you can reference, regardless
Even better if id's were strongly typed like:
public record ProductId(Guid Value);
Don't do that and you receive a contraption like this LineItem constructor that is asking for troubles.
I'm just assuming it's for the sake of keeping the video reasonably short. Wouldn't hurt to at least mention that pattern, though.
Other than that great tutorial, thanks!
I did cover it here: ruclips.net/video/LdrMdIabE1o/видео.html
I'm wondering if LineItem should be an entity? I don't think it needs an Id when it can use OrderId and productId to identify it. It does need its own table, so does that mean it's entity by default?
What happens when there are many line items? So that there are performance issues when loading all of them into memory. If you make it into an entity, you can solve that problem by just loading that one entity.
Great topic !
Thank you!
Great video as always :)
Thank you! Cheers!
At 0:40 you are describing the domain model, what exactly you are referring to? Are you pointing to entities, aggregate roots, and value objects or there is something else that belongs to the domain model?
With Domain model I mean the conceptual representation of problem domain in the diagram. Entities/Aggregates/Value objects are just tactical patterns to represent the Domain model in the code and enforce the invariants.
@@MilanJovanovicTech in a few words - are Domain Services part of Domain Model?
Great explanation and Great video.
I have tried it. It works also have tables with correct data but ....
When I read from table
_context.Orders.Include("ListItems").ToList();
It fails to load.
If I use it without include then it works but don't have ListItems data
_context.Order.ToList();
What's the error?
The only issue with records is that EF does not support it directly, so I don’t think you will be able to map these sort of value objects on the fly
What do you mean? Records work with EF. I'll show it on Tuesday.
@@MilanJovanovicTech Check out Khorikov’s article about the suitability of records as value objects. He puts forward a decent argument. I came across it a while back, which was enough for me to be deterred from using them with EF core, at least for the time being. Also, value objects aside, Microsoft documentation says that EF doesn't support updating with immutable entity types, which is not a total show stopper of course but does make few alarm bells ringing when you consider using them with EF in general. If you found a nice and neat way of incorporating them as value objects - I’m really looking forward to your video on Tuesday 👍
I'm on the model screen and I would like to see it expanded to customer has price list and product has different price per price list :) (sorry if something is later in the video about it :D )
I hope I didn't disappoint too much
@@MilanJovanovicTech you did not. However the concept I've mentioned in one hand seems to be fairly simple on the other hand it brings a lot of complexity. For example, customer can be moved from one price list to another between orders
Great Videos, Please can you do one on Composition and Or with Strategy Pattern, best struggling with these for months.
Good idea
@@MilanJovanovicTech Really? Thank you Your content has been really helpful great quality videos, well thought out/explained
I did ask you this a few months back and you gave me an answer I tried it I put together something that works but I wasn't sure it it still conforms to DDD and best practices.
1. Can we use interfaces in DDD Domain Modelling(if Possible is it advisable)?
The reason why I was asking is that I was trying to find the best way to model the data below.
The backstory is that in my App I need to communicate with Different renderers one renderer I am sending data over TCP and in the other I am writing data to a File.
Is it good practice to have different types of Objects In a collection in Json? Or would be better to Split the Data of One Json with the ID and Type I would then make another trip to the database/API using the Id from the first json so that I can get all the 'rendererDatas'.
If the below Json is up to standard what's the best way to model this in DDD?
[
{
"id": "859b6427-a84a-4ac7-1234-21864cf46c86",
"name": "string",
"description": "string",
"rendererDatas": [
{
"id": "ea0e7e36-ffe0-6543-83f0-23d46968b2aa",
"name": "string",
"DataType": "Viz",
"description": "string",
"IPAddress": "123.123.123",
"rendererAttributes": [{"FirstName": "John", "Number": "8"}]
},
{
"id": "ea0e7e36-6543-6543-83f0-23d46968b2aa",
"name": "string",
"DataType": "Ventuz",
"description": "string",
"FilePath": "C:\Data",
"Payload": "Json payload with Firstname and Number"
}
]
}
]
The UI that uses this API data has a List of more than object types but has the same base/parent. The User interface needs to do CRUD on the list, so one bit I was not sure about is how should the information be present in the API. So should GetItems() have all the different object types in one list in the response data? Or should it be multiple lists and it's up to the user to manage the data(fetching all the list and merging it in one)?
How we will access the Add method inside Order Model since its constructor is private ?
Order.Create is public, Add method is also public
@@MilanJovanovicTech it is public but not static
Why do we use the Create method? Why don't we use a constructor for this? After all, you can define all the checks during creation in the public constructor. What is the point of Create?
I don't like side-effects in constructor (raising domain events)
Great, thanks 🤩🤩
You’re welcome 😊
In this example, would modifying the price of a Product entity be restricted to an Order aggregate? How would you update a Product that did not belong to an Order?
The Product is completely unrelated to an Order. Unless you mean updating the price on a LineItem?
one more thing please
I cannot understand actually what is the difference when we create a recordcalled Money that has two props : Curreny and amount
And of simply adding two Columns inside the table called : Currency and Amount ?
Read about the Value object concept
Hey Milan.
What is the most effective way to change dependent class fields from other classes in the DDD approach?Just create methods inside the class to add/update/delete for each field? Do I really have to write a cqrs commands for every change to this entity?
Let's say, in addition to the usual fields in class "A", there are the following related to other classes that i want to change:
public IReadOnlyList? Cuisines => _cuisines?.ToList();
private readonly List _cuisines = new();
public IReadOnlyList? Reviews => _reviews?.ToList();
private readonly List _reviews = new();
public IReadOnlyList? Features => _features?.ToList();
private readonly List _features = new();
public IReadOnlyList? WorkSchedules => _workSchedules?.ToList();
private readonly List _workSchedules = new();
I don't think 😂
@@MilanJovanovicTech Yeah...any suggestions then?🙄 I mean, In my subject area, there is a Catering class that depends on the tables of Features, Cuisines, Reviews and Work Schedules, as written above. Splitting the Catering class into smaller ones does not seem optimal to me.
Hi
One question. How does it goes with EF core. I mean if we have associations with different class. EF core will treat them as separate tables, which could go wrong for example Price record. Please share insights regarding this. thanks
Make it an owned entity
It is not clear to me why not use a direct reference to Product and Customer objects inside Order instead of using their Ids.
Aggregates are not allowed to hold other aggregates. You can only reference them by ID.
@@MilanJovanovicTech could you please explain that? What would happen if we have a Product type property instead of Guid?
How do you map those in databases using EF?
Check out the next video
I am just curious. Why we were using GUID over all instead of Int as type? Is this GUID are sequenced?
To be able to provide the Id on the client side, among other things.
@@MilanJovanovicTechI really appreciate your quick response.... I see GUID are not sequenced does it benefit us really If our Database is not distributed.
With all of that code added ? Does Sku still need to be a record type ?
Does it?
Thank you!!
You're welcome!
Thanks!
Wow, thank you very much Daniel! 😊 I don't often get 'super thanks' so I'll remember this one for a while. Anything I can do for you to be helpful? Maybe you have a video suggestion?
I just want to say thanks. I like your videos and the level of details 😊.
email should also be a value object.
Agreed, but didn't want to steer off in that direction
Why did you make the _lineItems list readonly?
So that it's readonly 😅
But you have an Add method that adds a new LineItem to this readonly immutable list after it has been constructed
I would like to have a code...
I share it on Patreon
Can someone explain to me what does "Aggregate" mean?
This is from Martin Fowler: martinfowler.com/bliki/DDD_Aggregate.html
are you against strongly typed ids?
Not necessarily
We do not use the interface?
Which one?
@@MilanJovanovicTech I thought that when creating Customer we should create ICustomers and describe the logic inside it. ? But I'm not sure about that
Excuse me, I'm a newbie, when you create a function Create in Order Model, is there SRP rule scope in SOLID?
I consider all of it to be the SINGLE responsibility of the Order aggregate, therefore it's fine to have it in the class
Hi ! DDD does not respect SOLID principles ? Am I wrong?
How does it not respect SOLID?
To be fair - you do cover that here: ruclips.net/video/fe4iuaoxGbA/видео.html - I just had to find you doing it somewhere!!
It's a bit difficult going over everything in depth on a single video
You say from scratch - then jump straight into a project with a domain set up with no explanation of how you got there....for those of us not familiar with VS that first step would have been nice to see.
Sorry 🤷♂️😅
Just FYI, your title is misleading - you're not actually modelling anything here - you're implementing the domain model.
Appreciate the feedback
That has nothing to do with DDD, as it is the designing process, not the implementation.
For an introduction way too deep into technology
I focus more on the technology aspects, in general
@@MilanJovanovicTech Well, I find it confusing for a beginner to understand the idea behind DDD if you go straight and show source code.
In reality,
DDD is very unspecific, abstract and behind source code.
Especially,
when talking about Bounded Contexts,
Context Mapping (OHS, ACL etc.) which is actually a graphical process,
shown by unified diagrams,
which both,
stakeholders and developers,
can understand.
THOSE. WORD. CAPTIONS. AT. THE. BEGINNING. ARE. SO. ANNOYING.
Thanks
thanska. lot
Sure thing!