I've come to a bit of an impasse with the best way to implement a DDD problem, and am hoping for some advice from those with more experience, please.
I have a RecipeCollection
, which has a collection of type Recipe
(as you might expect). The abbreviated code looks like this:
public class RecipeCollection : IEntity<RecipeCollectionId>, IAggregateRoot
{
private readonly RecipeCollectionId id = new();
private readonly List<RecipeId> recipeIds = new();
public void AddRecipe(RecipeId recipeId) { /* not sure what to do here! */ }
...
}
public class Recipe : IEntity<RecipId>
{
public readonly string Name { get; private set; }
...
}
One of the business rules is that a Recipe
cannot have the same Name
within a RecipeCollection
. The obvious place to enforce this invariant is within RecipeCollection
, when adding a new Recipe
. However, RecipeCollection
only holds a list of RecipeId
, not a list of Recipe
itself.
Ideally, RecipeCollection
would hold a collection of Recipe
, which would make checking for duplicate Recipe.Name
easy. However, RecipeCollection
holds a collection of RecipeId
. It does this to avoid potential problems such as loading a RecipeCollection
from memory, which loads all its Recipe
s, which each in turn load another collection, and so on, and before you know it, you've loaded the entire database. I know I could use lazy loading, but I may use a data store where this isn't possible, so I'm forced to hold a collection of RecipeId
.
Is the best solution, in this case, to have the calling code, i.e. the command handler that retrieves the RecipeCollection
from the repo, check there are no duplicated Recipe
Name
s before adding the Recipe
? This would leak the business logic out of the Aggregate root in this instance, which is why I haven't committed to this solution. Or is there another solution/pattern I'm missing?