This is not a question with a clear answer, but I need some advice for my architecture. There might be a lot of different opinions about this topic.
I am trying to move my architecture from stupid entities to rich domain objects. In my current version I have abstract domain objects with readonly properties and methods that represent the business logic:
abstract class Project
{
public string PropertyName { get; protected set; }
public void Setup(SetupData data)
{
...
Save();
}
protected abstract void Save();
}
I derive from them to implement the mapping to the persistence entities and to implement the save logic:
class MongoProject
{
MongoProject(ProjectDocument document, Action<ProjectDocument> save)
{
MapFrom(document);
}
public override Save()
{
MapTo(document);
save(document);
}
}
This works very easily, the project is always valid because it has no public setter and it can be tested, even the mapping with the document.
But I also realized some problems:
- I always forgot to map some properties, there is no way to tell the MongoProject what it must serialize.
- Sometimes it is relativly complex to implement the mapping because you dont know inside the save method what has been changed, especially in a case where the project is a complex aggregate root. In my situation it was very easy to implement persistency with mongodb, but it was a nightmare with entity framework.
How do you solve persistency in your application and are there some other solutions for the mapping problem?
This is a bit of a broad question.
I dont ever implement my domain objects and my data access layer (saving to db, file, cloud, etc..) in the same class. There needs to be seperation of concerns. Your domain objects dont have to know how to save themselves to the database.
What i would do is create my domain objects inside a class, and create a seperate Data Access Layer, which is responsible for saving my data to whichever source i want it to be saved to. That way, each time you want to save your entities to a different location, your object model doesn't care and you dont have to change it at all.
For mapping POCO objects to DB entities, use AutoMapper, it will save you alot of boilerplate code, and you'll only have to configure it once
For example: