Search code examples
c#.netdomain-driven-designpersistence

DDD and Persistence. Again


I am struggling with persistence in Domain Driven Design. As far as I understand, domain model should never be persistent-aware. Let's say I am building a simple todo-list application. I have a task with following interface:

interface ITask
{
   bool IsCompleted {get;}
   string Description {get;}

   void Complete();
   void ChangeDescription(string description);
}

And the generic implementation should look like this:

class SimpleTask : ITask
{
    public SimpleTask(string description)
    {
       ChangeDescription(description);
    }

    public bool IsCompleted { get; private set; }
    public string Description { get; private set; }

    public void Complete()
    {
       IsCompleted = true;
    }

    public void ChangeDescription(string description)
    {
       // some validation here
       // ...
       Description = description;
    }
}

I want to have a description be necessary - because it's a business rule. So from this moment if I want to save this object via serializers I will fail because no parameterless constructor provided. And I shouldn't provide it because of no persistance-aware rule. If I model my task in a form of DTO\POCO I will end up with another problem - so called anemic model. Moreover, I don't want to provide setters to some properties.

So where is the solution to all of this? I can create a tightly-coupled saver that will know how to save and restore task state. But I can access only public properties and methods, what if internal logic of task will be complex and impossible to save\restore? Should I mark all fields in task internal and have a possibility to save inner state of object? Isn't it kinda code smell and violation of no persistence-aware rule?

How do you solve this?


Solution

  • From my understanding, Entity Framework is much less flexible than Hibernate so you will have to make a bit more compromises in the model. Vaughn Vernon, the author of Implementing Domain-Driven Design (IDDD) shows a great way of keeping self-encapsulated entities while making it easy to persist their state using Entity Framework.

    If you can use the persistence store of your choice, you may as well use a different strategy that doesn't involve so much impedance mismatch (e.g. event sourcing).