Infrastructure Ignorant/Anemic domain model?

by benl

An example project I put together recently highlighting recommended baseline architecture has got me thinking about the best approach to domain driven design and incorporating the Domain Model.

The domain model dictates that your entities encapsulate business logic. In facilitating such a requirement your model classes stray from the traditional POCO principles and can end up incorporating infrastructure artifacts such as persistence code and the like. The extreme end of this is being something like an ActiveRecord enabled model – whereby your ORM mappings are essentially C# properties adorned with attributes. This approach has a nasty whiff of Code Smell to me. Other evidence of this can include:

  • Having to derive from special classes defined in your ORM framework
  • Implementing special logic or types defined by your ORM framework
  • Redefining object identity for ORM purposes
  • Adding references to libraries required by your ORM framework

A concrete example of this is when trying to serialize entities from an NHibernate and lazy-loading enabled domain model. Due to the cruft required by NHibernate when proxying lazy-loaded collections, certain un-serializable types are introduced. Of course, the way around this side effect is to create Data Transfer Objects and move your data across the wire in this manner.

When layering in application design, the domain model naturally falls into the vertical. When enforcing strict layering the Anemic Domain Model is the only (simple) approach worth considering. The anemic domain model describes a collection of entities exhibiting only data. They can exist outside of an ORM context and depend on fewer packages. Rather than perhaps exposing static methods on your model classes i.e:

Publisher publisher = Publisher.GetById(id);

The danger of this approach is that data access occurs wherever methods on the domain model are invoked. Also, does the domain model have much use if not enforcing the business rules in the domain? After all, the domain model is rarely, if ever a candidate for reuse. I certainly can’t think of any case where it would be.

The alternative is to move those responsibilities out into some form of repository, for example:

Publisher publisher = DefaultRepository<Publisher>.FindById(id);

And in doing so you remove all your persistence concerns from the model. The entities then simply become dumb data holders and any persistence occurs only in the layers you allow it to.

I’m still not sure whether I prefer the former or the latter. DD purists will of course advocate the former, however my experience has been firmly around the latter approach. Can anyone help me decide?