I have decided to use 'Execute / CanExecute pattern' for validation of my entities. Also, I want to move my validation values (length of string, messages, etc) to XML file, but I am not sure that XmlReader logic in the Domain layer is an appropriate solution for it. (New to DDD.)
Where would you place the logic for reading an xml file according to DDD? Perhaps you can suggest another way to store validation data?
For example my Item class:
public class Item : Entity, IAggregateRoot
{
public string IdentityGuid { get; private set; }
public string Name { get; private set; }
public string Description { get; private set; }
public decimal Price { get; private set; }
public string PictureFileName { get; private set; }
public string PictureUri { get; private set; }
public string CatalogTypeId { get; private set; }
public CatalogType CatalogType { get; private set; }
public string BrandId { get; private set; }
public Brand Brand { get; private set; }
// Quantity in stock
public int AvailableStock { get; private set; }
// Available stock at which we should reorder
public int RestockThreshold { get; private set; }
// Maximum number of units that can be in-stock at any time (due to physicial/logistical constraints in warehouses)
public int MaxStockThreshold { get; private set; }
/// <summary>
/// True if item is on reorder
/// </summary>
public bool OnReorder { get; private set; }
public Item(
string name,
string description,
decimal price,
string pictureFileName,
string pictureUri,
string catalogTypeId,
CatalogType catalogType,
string brandId,
Brand brand,
int availableStock,
int restockThreshold,
int maxStockThreshold,
bool onReorder)
{
if (CanCreateItem(name, description, price, pictureFileName,
pictureUri, catalogTypeId, catalogType, brandId, brand,
availableStock, restockThreshold, maxStockThreshold).Any())
{
throw new CatalogDomainException($"Unable to create object {typeof(Item)} data is invalid.");
}
Name = name;
Description = description;
Price = price;
PictureFileName = pictureFileName;
PictureUri = pictureUri;
CatalogTypeId = catalogTypeId;
CatalogType = catalogType;
BrandId = brandId;
Brand = brand;
AvailableStock = availableStock;
MaxStockThreshold = maxStockThreshold;
OnReorder = onReorder;
}
/// <summary>
/// Validation for Creation of Item. Execute / CanExecute pattern
/// <param name="name"></param>
/// <param name="description"></param>
/// <param name="price"></param>
/// <param name="pictureFileName"></param>
/// <param name="pictureUri"></param>
/// <param name="catalogTypeId"></param>
/// <param name="catalogType"></param>
/// <param name="brandId"></param>
/// <param name="brand"></param>
/// <param name="availableStock"></param>
/// <param name="restockThreshold"></param>
/// <param name="maxStockThreshold"></param>
/// <returns>int: Collection of string error message</returns>
/// </summary>
public IReadOnlyList<string> CanCreateItem(string name,
string description,
decimal price,
string pictureFileName,
string pictureUri,
string catalogTypeId,
CatalogType catalogType,
string brandId,
Brand brand,
int availableStock,
int restockThreshold,
int maxStockThreshold
)
{
var errors = new List<string>();
// name
if (string.IsNullOrEmpty(name))
errors.Add("Name must be at least three characters long.");
if (name.Length < 3)
errors.Add("Name must be at least three characters long.");
if (name.Length > 50)
errors.Add("A name cannot be more than fifty characters long.");
// description
if (string.IsNullOrEmpty(description))
errors.Add("Description must be at least fifth characters long.");
if (name.Length < 5)
errors.Add("Name must be at fifth three characters long.");
if (name.Length > 1000)
errors.Add("A name cannot be more than thousand characters long.");
// price
if (price < 0)
errors.Add("Price must be greater than zero.");
// pictureFileName
if (string.IsNullOrEmpty(pictureFileName))
errors.Add("PictureFileName cannot be empty.");
// pictureUri
if (string.IsNullOrEmpty(pictureUri))
errors.Add("PictureUri cannot be empty.");
// catalogTypeId
if (string.IsNullOrEmpty(pictureUri))
errors.Add("CatalogTypeId cannot be empty.");
// catalogType
if (string.IsNullOrEmpty(catalogTypeId))
errors.Add("CatalogTypeId cannot be у.");
// catalogType
if (catalogType == null)
errors.Add("CatalogType cannot be null.");
// brandId
if (string.IsNullOrEmpty(brandId))
errors.Add("BrandId cannot be empty.");
// brand
if (brand == null)
errors.Add("Brand cannot be null.");
// availableStock
if (availableStock < 0)
errors.Add("AvailableStock must be Zero or greater.");
// restockThreshold
if (restockThreshold < 0)
errors.Add("RestockThreshold must be Zero or greater.");
// maxStockThreshold
if (maxStockThreshold < 0)
errors.Add("MaxStockThreshold must be Zero or greater.");
return errors;
}
}
My XML file with validation data. (Just for example)
<ItemValidationData>
<ItemProperty>
<Name>Name</Name>
<ConstraintName>MinNameLength</ConstraintName>
<Value>3</Value>
<Message>Name must be at least three characters long.</Message>
</ItemProperty>
<ItemProperty>
<Name>Name</Name>
<ConstraintName>MaxNameLength</ConstraintName>
<Value>50</Value>
<Message>A name cannot be more than fifty characters long.</Message>
</ItemProperty>
</ItemValidationData>
Aucun commentaire:
Enregistrer un commentaire