我正在使用Entity Framework v4。我試圖通過覆蓋SaveChanges方法來實現一些邏輯來驗證我的實體,然後才能保存它們。我也是我的實體的POCO。如何避免使用正確類型的鑄件
我通過執行以下操作獲取修改和新實體的列表。
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");
}
}
這裏是我的GetValidator方法的代碼:
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;
}
的問題是,我得到一個失敗的話說:
Unable to cast object of type 'Blah.Validation.ConcreteValidator' to type 'Blah.Validation.IValidator`1[Blah.Validation.IValidatable]'
,我可以做的唯一的事情擺脫這個錯誤是先將對象轉換爲正確的類型,但我不想投擲所有東西。
這裏是我的IValidator
public interface IValidator<TEntity>
where TEntity : IValidatable
{
IEnumerable<ValidationError> Validate(TEntity entity);
}
好了接口,現在我的瘋狂背後的一些推理。我試圖堅持SRP,我不希望我的對象能夠驗證自己。所以我的IValidatable接口只是一個標記。我試過了,沒有標記,它沒有任何區別。我也不希望我的單元測試體積龐大,但我知道我可以爲驗證和實際實體分開單元測試。
接下來,我很懶惰,我不想寫映射器等。另外,我想有一個更多的約定配置,如果有驗證提供它將被使用。
我在很多地方都使用過泛型。我喜歡它提供的功能,但我不是專家,目前它正在咬我。
反正有這個嗎?避免必須轉換對象的方法,以便運行時可以找出將其轉換爲什麼的方法?我使用Ninject的依賴注入是否有幫助
UPDATE: 按照要求,具體的校驗
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" };
}
}
請寄出'ConcreteValidator'的定義。 – 2010-10-25 11:30:49
@Peter,我發佈了代碼。 :) – uriDium 2010-10-25 11:39:48
SomeObject擴展IValidatable嗎? – 2010-10-26 00:50:33