I have a scenario where a domain entity property needs to be verified to be unique before it can be saved to the database. Here is a simple Product class. Let’s assume I want to validate that when creating a new Product that the ProductKey string property is unique:
public class Product : EntityBase
{
int ID { get; set; }
string ProductKey { get; set; }
int CategoryID { get; set; }
bool IsValid
{
get
{
if (string.IsNullOrEmpty(ProductKey))
{
ValidationErrors.Add("ProductKey Required.");
}
if (CategoryID == 0)
{
ValidationErrors.Add("CategoryID Required.");
}
/* Validation that the product key is unique could go here? i.e. requires a database read. */
return ValidationErrors.Count() == 0;
}
}
}
Since I’m using Domain Driven design the Product entity has no knowledge of persistence or the service layers. I could just add a check to the Service method as follows:
public class ProductService
{
private IProductRepository _productRepository = new ProductRepository();
public int CreateProduct(Product item)
{
if (item.IsValid)
{
if (ProductKeyIsUnique(item.ProductKey))
{
_productRepository.Add(item);
}
else
{
throw new DuplicateProductKeyException();
}
}
}
private bool ProductKeyIsUnique(string productKey)
{
return _productRepository.GetByKey(productKey) == null;
}
}
This is simple enough but ideally I would like such logic to live in the domain model. Perhaps by raising some kind of validation event that can be caught by the service layer?
Is there a best practice or known design pattern for this type of scenario?
Product key uniqueness is not domain object knowledge. So you don’t need domain validation for it. Why Product should care about key uniqueness? In my opinion it is an application layer responsibility. Your solution seems valid and right for me.