I am using Entity Framework v4. I am trying to implement some logic to Validate my entities before they are saved by overriding the SaveChanges method. I am also POCO for my entities.
I get a list of modified and new entities by doing the following.
var entities = (ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
.Select(ose => ose.Entity).OfType<IValidatable>();
foreach(var entity in entities)
{
var validator = validatorProvider.GetValidator(entity);
var errors = validator.Validate(entity);
if (errors.Count() > 0)
{
throw new Exception("A validation error");
}
}
And here is the code for my GetValidator method:
private static IValidator<TObject> GetValidator<TObject>(TObject obj) where TObject : IValidatable
{
var objType = obj.GetType();
var validatorType = Type.GetType("SmsPortal.Validation." + objType.Name + "Validator");
var varValidator = Activator.CreateInstance(validatorType);
return (IValidator<TObject>)varValidator;
}
The problem is that I am getting a failure saying:
Unable to cast object of type 'Blah.Validation.ConcreteValidator' to type 'Blah.Validation.IValidator`1[Blah.Validation.IValidatable]'
The only thing that I can do to get rid of this error is to cast the object to the right type first but I don't want to have to cast everything.
Here is my interface for IValidator
public interface IValidator<TEntity>
where TEntity : IValidatable
{
IEnumerable<ValidationError> Validate(TEntity entity);
}
Okay, now for some reasoning behind my insanity. I am trying to stick to SRP and I don't want my objects to be able to validate themselves. So my IValidatable interface is just a marker. I have tried it with and without the marker, it makes no difference. I also don't want my unit tests to be bulky although I know I could have separate unit tests for validation and for the actual entity.
Next I am quite lazy and I don't want to have to write mappers etc. Also I would like to have a more convention over configuration and if there is a validator provided it will be used.
I have used generics in a lot of places. I like the functionality it has given but I am not expert and it is biting me at the moment.
Is there anyway around this? A way to avoid having to cast the object so that the runtime can figure out what to cast it to? I am using Ninject's dependency injection if that helps
UPDATE: As requested, the concrete validator
public class ConcreteValidator : IValidator<SomeObject>
{
public IEnumerable<ValidationError> Validate(SomeObject entity)
{
if (string.IsNullOrEmpty(entity.Name))
yield return new ValidationError { Message = "Name is mandatory", Property = "Name" };
if (entity.Name != null && entity.Name.Length > 50)
yield return new ValidationError { Message = "Name must be less than 50 characters", Property = "Name" };
}
}