title: How should I materialize DDD entities with private setters from the persistence layer?
body: <p>I'm just starting to figure out DDD. Anemic domain models (that I learn were actually no more than persistence models) and pushing logic into the view models just wasn't cutting it. So I've modeled one of the more complex contexts (a feed nutrition/price optimizer). I'm totally on board with the fact that the DDD entities have private setters and expose readonly collections, and that the only way to mutate them is to call methods on the entities. Very easy to test, hard to misuse.</p>
  
  <p>Here's my problem. It's straightforward to save this thing to the database. What's not obvious to me is how to materialize it again without breaking encapsulation.</p>
  
  <p>I've been using Entity Framework to load data models. I know it is capable of using the domain entities' private setters, but: 1) the magic of reflection can be misleading to reason about. 2) I definitely don't want to try to skip the data models and coerce the domain models to try to play well with EF. 3) The database is slightly less normalized than the domain model. 4) I don't think EF plays well with <code>IReadOnlyList&lt;&gt;</code>.</p>
  
  <p>I also tried reconstructing and replaying the method calls which would cause the entity to be in an equivalent state, but that seems like unnecessary complexity. It isn't obvious to me whether the code is correct. Also this method would trigger quite a lot of linear programming solving and lag.</p>
  
  <p>In order to keep the domain entities clean, the last resort I can think of is an internal static factory method on each entity called <code>Materialize</code> which receives the fields as parameters and returns a new instance of the entity. The respository should be the only thing accessing it. Is this a good solution? What else should I consider?</p>
  
  <p>Edit: rather than materializing saved state, I'm having my repositories simulate event sourcing (the replay approach). I like this direction. The database is not event sourcing yet but could easily switch at any point, since the repositories are hiding that.</p>