I am developing a CMS type application and am looking to use some ddd tactical patterns. Here is the situation:
The application deals with the authoring and publishing of items.
Items are grouped together in a workflow group. Within that group, one item may be marked as 'Published', one item as 'Working' and any number as 'Archived'.
A item can only be edited when it is in the 'Working' state.
When a working item is published it replaces its corresponding published item (if there is one), which would be then marked as Archived.
If no draft exists, a new working version may be created by copying the published version or any of the archived versions.
The question is, following the guidance that Aggregates should encapsulate system invariants, should Workflow Group be an Aggregate root - encompassing all its items?
My worry is that this would make quite a large aggregate, and it would stop items being globally accessible (i.e. all interaction would have to go through the Workflow Group AR).
The alternative I see is to make Item an Aggregate Root, and then have a Domain Service deal with the transactions and invariants. For instance:
PublishWorkingItem(int itemId)
{
Item workingItem = itemRepo.GetWorkingItem(itemId);
Guid groupId = workingItem.GroupId;
Item publishedItem = itemRepo.GetPublishedItemForGroup(groupId);
if(publishedItem != null)
{
publisheditem.Archive();
}
workingItem.Publish();
}