Preventing Dirty Domain Object Persistance
The add recipes feature has currently been implemented in a way that does not allow for
dirty domain objects to be persisted (saved to the database). The recipe object
constructor must be passed all the essential object properties to prevent a partial
object from being persisted, as shown below:
public Recipe(string title, IList recipeIngredients, string cookingMethod) : this()
{
//TODO - Add the recipe creator (ie. user) to the domain signature
Check.Require(title != null && title.Trim() != string.Empty, "title must be provided.");
Check.Require(recipeIngredients != null, "recipeIngredients must be provided.");
Check.Require(cookingMethod != null && cookingMethod.Trim() != string.Empty, "method must be provided.");
Title = title;
Ingredients = recipeIngredients;
CookingMethod = cookingMethod;
}
However this means that the state of the recipe object must be maintained across the 3
separate add recipe views. I’ve had to use both hidden fields on the views and the
TempDataDictionary to maintain this state. It has become clear to me that there may be a
better way to implement this if I use a RecipeDraft domain object in addition to the
Recipe object. However making this change will take a while so I need to weigh up
whether I think it is worth while.
Advantages
- Users can add draft recipes and return later to complete them
- More readable controller methods (RecipeIngredientDtos is a nasty object name!)
- No need to maintain temporary state across views (using hidden fields and the TempDataDictionary)
- Simplifed View Models
Disadvantages
- Time to refactor the code and unit tests
- More records in the database (potentially higher cost)
- More I/O operations on the database (slower website page loads)
On balance I think the advantages are outweigh the disadvantages, so I will be
refactoring the code to use a RecipeDraft object. This will be the constructor of the
RecipeDraft object:
public RecipeDraft(string title) : this()
{
//TODO - Add the recipe creator (ie. user) to the domain signature
Check.Require(title != null && title.Trim() != string.Empty, "title must be provided.");
Title = title;
}