In the battle of Rich vs. Anemic domain models, the internet is full of philosophical advice but short on authoritative examples. The objective of this question is to find definitive guidelines and concrete examples of proper Domain-Driven Design models. (Ideally in C#.)
For a real-world example, this implementation of DDD seems to be wrong:
The WorkItem domain models below are nothing but property bags, used by Entity Framework for a code-first database. Per Fowler, it is anemic.
The WorkItemService layer is apparently a common misperception of Domain Services; it contains all of the behavior / business logic for the WorkItem. Per Yemelyanov and others, it is procedural. (pg. 6)
So if the below is wrong, how can I make it right?
The behavior, i.e. AddStatusUpdate or Checkout, should belong in the WorkItem class correct?
What dependencies should the WorkItem model have?
public class WorkItemService : IWorkItemService {
private IUnitOfWorkFactory _unitOfWorkFactory;
//using Unity for dependency injection
public WorkItemService(IUnitOfWorkFactory unitOfWorkFactory) {
_unitOfWorkFactory = unitOfWorkFactory;
}
public void AddStatusUpdate(int workItemId, int statusId) {
using (var unitOfWork = _unitOfWorkFactory.GetUnitOfWork<IWorkItemUnitOfWork>()) {
var workItemRepo = unitOfWork.WorkItemRepository;
var workItemStatusRepo = unitOfWork.WorkItemStatusRepository;
var workItem = workItemRepo.Read(wi => wi.Id == workItemId).FirstOrDefault();
if (workItem == null)
throw new ArgumentException(string.Format(@"The provided WorkItem Id '{0}' is not recognized", workItemId), "workItemId");
var status = workItemStatusRepo.Read(s => s.Id == statusId).FirstOrDefault();
if (status == null)
throw new ArgumentException(string.Format(@"The provided Status Id '{0}' is not recognized", statusId), "statusId");
workItem.StatusHistory.Add(status);
workItemRepo.Update(workItem);
unitOfWork.Save();
}
}
}