When looking at the post "Should Entities in Domain Driven Design and Entity Framework be the same?" the accepted answer states that domain entities and EF Entities can only be the same when using code first. This so that the entities can remain "pure".
However, because of this inpediment: "Discussion on many-to-Many relationships (without CLR class for join table)" it is not possible to create an order entity with a collection of product entities without specifying a special entity for the association table (orderline entity).
I now see colleagues taking these association tables into their domain entities and i feel that is wrong because it hints towards coping with persistence and not towards being true to the domain. They are not "pure" anymore in my opinion.
Would you say that it is impossible to have the same Domain entities in EF Core because of the association table entities? How can i cope with this in EF Core?
But in a regular/classic Ordering domain there is a need for an orderline (or order-line-item or whatever you want to call it) because you need to store the quantity and the item price along the product ID.
In most DDD examples this item is a Value object from the DDD point of view and an Entity from the Persistence point of view. If you are wondering how a Value object could be an ORM Entity you should read Persisting Value Objects from the book Implementing Domain Driven Design by Vaughn Vernon.
There are, however cases when the Domain model does not fit 100% percent with the Persistence model. In such cases one needs to attach some meta information to the Domain models in order to match the Persistence models. In general you have two options:
you can add the metadata to some external files, like XML-files;
it has the advantage that it keeps the Domain model agnostic in regard to the persistence but
it has the disadvantage that one must remember to change the external files when the Domain model changes
you can annotate the Domain models
it has the advantage that it is easy to change at the same time the Domain model and the Persistence model by having the information in the same file; it follows the principle: "things that change together stay together" (Common Closure Principle)
it has the disadvantage that it pollutes the Domain model with Infrastructure concerns
If I have to choose, I tend to choose to annotate the Domain models, but you should make that decision by yourself.
The problem
I am creating an IP address management solution. I want to be able to add attributes to each object in my model. Before I go in further I will explain what an attribute is. An attribute is simply a name/value pair that we will associate to an object. For example:
Network Object
Attribute - Building=5
Attribute - Department=Sales
Host Object
Attribute - Building=5
Attribute - Department=Sales
The reason for adding attributes is to query the system to find out information. For example, which networks do we have in building 5 or find me all objects with an attribute that equals X.
Design of DDD System
The network is a model which is manipulated via a service. For example there is a network service which can perform a CRUD, it accepts a network object.
Questions/Thoughts of adding attributes that span across multiple entities
Assume I have an attribute collection (which includes the actual attribute in an array inside that collection object). This attribute collection will be added to my network.
Should we add every part of functionality for an attribute inside the service of every entity like the network?
Should we create a separate service for the attribute, but here I am not sure how we would manage the objects that require attributes for them?
The type of questions we want to ask the system with attributes:
Q: How do you get all entities with an attribute of X?
Now I don't want to think about the database as that is later on. I just want an idea on what we can do from the object level using Domain Driven Design.
What you seem to have is a classification system. It will in all probability be a sub domain. I don't think you want to add this functionality to each domain aggregate root that requires classification.
In any event you do mention that it is used mainly for querying/finding objects. I would go for a generic sub domain where you can select qualifying ARs from one or more BCs and then assign these additional attributes to the AR in the Classification BC.
You would then use the Classification BC to find the relevant Ids and additional information about the ARs you require and then navigate from there.
From what I've read and implemented, DTO is the object that hold a subset of value from a Data model, in most cases these are immutable objects.
What about the case where I need to pass either new value or changes back to the database?
Should I work directly with the data model/actual entity from my DAL in my Presentation layer?
Or should I create a DTO that can be passed from the presentation layer to the business layer then convert it to an entity, then be updated in the DB via an ORM call. Is this writing too much code? I'm assuming that this is needed if the presentation layer has no concept of the data model. If we are going with this approach, should I fetch the object again at the BLL layer before committing the change?
A few thoughts :
DTO is a loaded term, but as it stands for Data Transfer Object, I see it more as a purely technical, potentially serializable container to get data through from one point to another, usually across tiers or maybe layers. Inside a layer that deals with business concerns, such as the Domain layer in DDD, these little data structures that circulate tend to be named Value Objects instead, because they have a business meaning and are part of the domain's Ubiquitous Language. There are all sorts of subtle differences between DTO's and Value Objects, such as you usually don't need to compare DTO's, while comparison and equality is an important concern in VO's (two VO's are equal if their encapsulated data is equal).
DDD has an emphasis on the idea of rich domain model. That means you usually don't simply map DTO's one-to-one to domain entities, but try to model business actions as intention-revealing methods in your entities. For instance, you wouldn't use setters to modify a User's Street, City and ZipCode but rather call a moveTo(Address newAddress) method instead, Address being a Value Object declared in the Domain layer.
DTO's usually don't reach the Domain layer but go through the filter of an Application layer. It can be Controllers or dedicated Application Services. It's Application layer objects that know how to turn DTO's they got from the client, into the correct calls to Domain layer Entities (usually Aggregate Roots loaded from Repositories). Another level of refinement above that is to build tasked-based UIs where the user doesn't send data-centric DTO's but Commands that reflect their end goal.
So, mapping DTO's to Entities is not really the DDD way of doing things, it denotes more of a CRUD-oriented approach.
Should I work directly with the data model/actual entity from my DAL in my Presentation layer?
This is okay for small to medium projects. But when you have a large project with more than 5 developers where different layers are assigned to different teams, then the project benefits from using a DTO to separate the Data Layer from the Presentation Layer.
With a DTO in the middle, any changes in the presentation layer won't affect the data layer (vice versa)
Or should I create a DTO that can be passed from the presentation layer to the business layer then convert it to an entity, then be updated in the DB via an ORM call. Is this writing too much code? I'm assuming that this is needed if the presentation layer has no concept of the data model. If we are going with this approach, should I fetch the object again at the BLL layer before committing the change?
For creating a new entity, then that is the usual way to go (for example "new user"). For updating an existing entity, you don't convert a DTO to an entity, rather you fetch the existing entity, map the new values then initiate an ORM update.
UpdateUser(UserDto userDto)
{
// Fetch
User user = userRepository.GetById(userDto.ID);
// Map
user.FirstName = userDTO.FirstName;
user.LastName = userDTO.LastName;
// ORM Update
userRepository.Update(user);
userRepository.Commit();
}
For large projects with many developers, the disadvantage of writing too much code is minimal compared to the huge advantage of decoupling it provides.
See my post about Why use a DTO
My opinion is that DTOs represent the contracts (or messages, if you will) that form the basis for interaction between an Aggregate Root and the outside world. They are defined in the domain, and the AR needs to be able to both handle incoming instances and provide outgoing instances. (Note that in most cases, the DTO instances will be either provided by the AR or handled by the AR, but not both, because having one DTO that flows both ways is usually a violation of separation of concerns.)
At the same time, the AR is responsible for providing the business logic through which the data contained in the DTOs are processed. The presentation layer (or any other actor including the data access layer, for that matter) is free to put whatever gibberish it wants into a DTO and request that the AR process it, and the AR must be able to interpret the contents of the DTO as gibberish and raise an exception.
Because of this requirement, it is never appropriate to simply map a DTO back to its Entity counterpart.
The DTO must always be processed through the logic in the AR in order to affect changes in the Entity that may bring it to the state described by the DTO.
I am following this example: Using NHibernate with ServiceStack
In the Contacts class library is there way to not have to create another Product class since we already have the Model or is this required? Seems like dependency injection could be used here.
Also could I move the model and mappings into thier own class library outside of the Services project?
How would I return model that had a property that was another model? I.e. Say we had an employee model that was linked to a person model by Id and the person model contained the employee Date Of Birth, I am not seeing how I would return that.
You don't have to create seperate models (or DTOs), however, I think when dealing with different ORMs the custom DTOs will make life easier. You can easily translate the properties with ServiceStack's property translater or something like AutoMapper.
I would create your DTOs in the manner that you want others to consume them. In other words you DTO's don't need to align with the underlying tables. You can combine models and flatten the data into useful DTOs. In your example the Employee class could expose the date of birth and any other person properties.
You can easily keep your DTOs in a separate project. I have done this in projects where I wanted to re-use the DTO classes elsewhere without including the services.
Sorry if the question sounds too vague. I will improve based on your feedback.
I have managed to prepare a UML model of a problem domain. This is essentially a class diagram describing class attributes and aggregation relationships amongst classes. Intention now is to fill data.
For example, class-A aggregates N instances of Class-B. I would like to create a data model that has data for one instance Class-A and 5 instances of Class-B.
Basically, data pertaining to this meta model is available in a document (e.g. xls, framemaker) and it should be possible to read the source and populate the data model.
Are there tools that will let me create this data model? Please advise.
You have two options to creates your database model from our UML model.
You can use the UML model and then add a code generator to generate the database then finally reverse it with a database modeling tool such as erwin.
Another approach is to use the database modeling profile inside your UML model. It means that ypu model and add database stereotype related to java ORM.
Both works pretty well.