我正在尝试使用Microsoft企业验证方法在我的实体中执行验证。在我的基类中,我有以下方法:
public class BaseEntity
{
public bool IsValid()
{
return Validate().IsValid;
}
public ValidationResults Validate()
{
return Validation.Validate<this.GetType()>(this);
}
这个问题是,即使BaseEntity的子类调用IsValid,this.GetType()也总是返回BaseEntity,而不是Subclass的类型。我不想为每个实体重写这个代码,因为这似乎非常不喜欢。还有其他办法吗?
我确实有一个受保护变量受保护的Type _validationType的想法,并且在每个实体中将它设置为该实体的.GetType值,但似乎必须有更好的方法来执行此操作。
更新的
显然没关系。 this.GetType()似乎正如我所希望的那样工作。不知道为什么以前没有。
我还将Validate()方法更改为使用以下代码:
return ValidationFactory.CreateValidator(this.GetType()).Validate(this);
答案 0 :(得分:2)
它的very un-OO like
基类可以了解有关子类的任何信息。这有效的方式。
如果您想了解有关子类的信息,则需要覆盖此方法。
答案 1 :(得分:2)
当您使用O / RM映射器(如LINQ to SQL,NHibernate或LINQ to Entities(ADO.NET实体框架))时,我会采用另一种验证方法。我会让实体完全清除验证(因此没有BaseEntity.Validate()。您可以将此验证逻辑移动到ObjectContext(EF)/ DataContext(L2S)/ Session(NH)并在数据库提交期间触发验证查看下面的LINQ to SQL示例:
public partial class NorthwindDataContext
{
public override void SubmitChanges(ConflictMode failureMode)
{
var invalidResults = (
from entity in this.GetChangedEntities()
let type = entity.GetType()
let validator = ValidationFactory.CreateValidator(type)
let results = validator.Validate(entity)
where !results.IsValid
from result in results
select result).ToArray();
if (invalidResults.Length > 0)
{
// You should define this exception type
throw new ValidationException(invalidResults);
}
base.SubmitChanges(failureMode);
}
private IEnumerable<object> GetChangedEntities()
{
ChangeSet changes = this.GetChangeSet();
return changes.Inserts.Concat(changes.Updates);
}
}
如果您的实体无效,将抛出ValidationException。您可以捕获该特定异常并迭代您在其上定义的InvalidResults属性。
当您需要更多信息时,我建议您阅读this文章。它还描述了如何使用Entity Framework执行此操作。
祝你好运。答案 2 :(得分:1)
除了关于验证的所有内容之外,还有一种方法可以编写基类'方法,让它知道调用它的实际子类类型。
嗯......一种假装的方式,至少(没有违反任何OO
规则,加布里埃尔)。它非常优雅,效果非常好:
public ValidationResults Validate<TEntity>(this TEntity e) where TEntity : BaseEntity
{
return Validation.Validate<TEntity>(e);
}
扩展方法的一大好处......:)
答案 3 :(得分:0)
您可以使IsValid()
和Validate()
成为虚拟方法,以便在子类中提供一些自定义定义。
答案 4 :(得分:0)
将类型逻辑移出BaseEntity更清晰。
public class BaseEntity
{
public bool IsValid()
{
return Validate().IsValid;
}
public ValidationResults Validate()
{
return Validation.Validate(this);
}
}
public class Validation
{
public static ValidatorResults Validator<T>( T entity )
where T : BaseEntity
{
return ValidationFactory.CreateValidator(entity.GetType()).Validate(entity);
}
}