I'm not sure where to place the following checks I have now in the material domain class. The issue is, that I need to validate that material exists and is valid in external database. Only after that validation I can be sure that I can use this material in our new project and store it in database. The Material object is part of collection in Order aggregate object. This is simplified example to demonstrate the issue.
Material class
public class Material
{
public int? Id { get; private set; }
public int RequestId { get; private set; }
public int MaterialNumber { get; private set; }
public int Quantity { get; private set; }
// EF
private Material()
{
}
public Material(int requestId, int materialNumber, int quantity,
string materialType, string materialStatus, string materialCondition)
{
if (materialCondition != "ZPR0")
{
throw new InvalidOperationException("Material condition is not valid.");
}
if (materialType != "FERT" || materialType != "UNBW")
{
throw new InvalidOperationException("Material type is not valid.");
}
if (materialStatus != "Z2" || materialStatus != "Z3" || materialStatus != "Z4")
{
throw new InvalidOperationException("Material status is not valid.");
}
Id = requestId;
MaterialNumber = materialNumber;
Quantity = quantity;
}
}
Order class
public class Order : IAggregate
{
public int? Id { get; private set; }
public IList<Material> Materials { get; }
// EF
private Order()
{
}
public AddMaterial(Material material)
{
Materials.Add(material);
}
}
Should I load materialType, materialStatus and materialCondition values from the database and pass it into domain entity inside Application layer (API) ? Or should I call some domain service (or repository method inside application layer) or domain validator to call some method IsMaterialValid(materialType, materialStatus and materialCondition) and after that materialize the Material object ? Its simple issue but I dont know how to handle it properly.
I am not sure if this type of validation should be part of the domain object or not. And if not, is it possible to place it inside application layer or is it better to incorporate some domain service somehow ?
The solution which I lean, is to create IsMaterialValid(int number) as database procedure and call it from repository in application layer, after that validation, create material object and pass it to Order object. It seems like most direct and easy way. What I don't like is that I will outsource the domain validation into database procedure (but as a plus I will still be dependent on validation method defined in repository interface).
Any idea ?
InvalidOperationException
suggests that the function is not available--or at least not in a state where it can take calls. AValidationException
orInvalidParameterException
might be more informative.materialCondition
,materialStatus
andmaterialCondition
have to do this any particular instance of Material. They are arguments passed in to the "Detail" method that constrain the values of properties on Matrial. Why are those three arguments not members of Material? Is this partial code?