Reputation: 4607
I want to add a validation class to an Entity, so it can check it is valid before being entered into the database. (The check is for business requirements, not db constraints).
I have the class
public class MyEntity
{
private readonly IValidatorFactory _validatorFactory;
public MyEntity(IValidatorFactory validatorFactory)
{
_validatorFactory = validatorFactory;
}
//Entity Properties Removed For Clarity
public void Validate()
{
if(_validatorFactory == null)
{
throw new ArgumentNullException("Validator Factory was null, cannot validate this item");
}
var validator = _validatorFactory.GetValidator(this.ItemTypeId);
valid = validator.Validate();
}
}
Using dependency injection, I am struggling to see how I can cleanly resolve the dependency when the project uses EF6. If I return a DbSet, it will of course not know about the requirement for the validator. A parameterless constructor is required.
Upvotes: 3
Views: 870
Reputation: 10581
Firstly, I don't think you should be trying to use DI with your entities. Validation should probably also occur within your entity itself rather than using an external validator (passed into the Validate
method or created with a ValidatorFactory
).
Entity Framework has multiple ways to do validation built in. Have you tried any of those?
The simplest form would be adding attributes to properties, such as Required
and StringLength
. For more complex validation you could have your entities implement IValidateObject
or override DbContext.ValidateEntity
.
Using any of those methods a DbEntityValidationException
will be raised when validation fails when you call DbContext.SaveChanges
. You can also trigger validation without throwing exceptions by calling DbContext.GetValidationErrors
.
Upvotes: 4
Reputation: 14064
The need for an external validator feels like a smell to me - not to mention the convoluted ValidatorFactory
.
If you want to avoid the anemic domain antipattern as you rightly said, you might as well include validation in the entities themselves and keep them valid at all times.
Another thing that doesn't make sense to me is that you identified 4 entities with "different business requirements and validation rules". IMO this is precisely where you need the specificity of ad hoc entities each enforcing its own rules internally, as opposed to the genericity of an external Validator abstraction.
Regarding the similar part of your 4 entities, i.e. the data, I would try to extract it to meaningful Value Objects and compose your entities of these objects.
Upvotes: 2