I recently came upon a question in the Domain Driven Design Yahoo! Groups asking whether or not the presentation layer should interact directly with repositories or through a method on the entity (domain model). Having just finished Nilsson’s Applying Domain Driven Design Patterns and (finally) getting my head around LINQ to SQL on my current project, I decided to weigh in on the matter.
As always, it depends. You can indeed allow the presentation layer to use the repository directly, just as you can allow the presentation layer to use a factory to create your entities. Your current implementation is something I started off with when I started trying to do DDD, and follows more of the Active Record pattern, as mentioned by another responder, thought Active Record, by definition, matches the database table field for field.
You have several options:
- Use your current approach. You’ll probably need to merge your repository and entity by using static methods and properties, though, which can make it messy, and I wouldn’t recommend it. That’s why I stopped using this approach, anyway.
- Add a validation mechanism to your repository to validate your entities or, if your entities validate themselves, report the entities’ validation before you save.
- If you really like the Save method on your entity and you use .NET or a dynamic language (not sure about other platforms), you can use extension methods to “add” a Save method that wraps a call to your repository. This is really option 2 with some syntactic sugar.
- BEST PRACTICE (?): Use a Unit of Work, such as LINQ to SQL’s DataContext, Entity Framework’s ObjectContext, or NHibernate’s / SubSonic 3’s ISession to manage transactions and repsoitories, then call SubmitChanges() through the unit of work.
The Unit of Work pattern can be a little hard to understand at first, but it is quite powerful and great for managing rollbacks (which are extremely difficult if you always wrap your unit of work/repositories in the entity methods).
For reference, try these links:
For keeping LINQ to SQL and Entity Framework persistence ignorant (PI), see: