My business layer has objects that implement IValidatableObject. I want my business rules for these entities in an external assembly and then call the validator for the type in:
public IEnumerable<ValidationResult> Validate(ValidationContext vc){}
I was going to use DI to inject the validator into the constructor of the type implementing the IValidatableObject interface.
public Customer(ICustomerValidator validator)
{
this.Validator = validator;
}
I figured I'd call out to Unity in the types factory and inject from there.
But then alot of the time the entity is just read not modified i.e. a Customer entity. It doesn't always need a validator because it might just be there to support a use case and not actually be modified by it.
So I figure I can either:
- Make CustomerEdit classes and then use constructor injector on those only and not on say CustomerRead classes but this leads to a class explosion that I dont really want for this application.
- Have a single customer class and inject the validator when it's needed.
For 2 as above the Validate method of the implementation for IValidatableObject interface seems the appropriate place. The trouble is in many cases this method is called by code other than my own. For instance from Entity Framework and for some types, from MVC as they will be used as model classes.
So now I'm in the position of having to override methods in framework code just so I can DI. This doesn't "seem" right but to be honest I don't know why.
The next thing I looked at is the GetService() method of the ValidationContext.
public IEnumerable<ValidationResult> Validate(ValidationContext vc)
{
var customerValidator = (ICustomerValidator)vc.GetService(typeof(ICustomerValidator));
return customerValidator.Validate();
}
But if I start doing this, haven't I just stepped into the whole realm of the ServiceLocator anti pattern, breaking the Law of Demeter and making test a total pain?
So is there a cleaner way out of this or is it just a matter of choosing my trade offs from what I've outlined?