对于本示例,我有两个类,它们是针对LINQ-to-SQL模型类的部分类。
public partial class Foo
{
public bool IsValid
{
get { return (GetRuleViolations().Count() == 0); }
}
public IEnumerable<RuleViolation> GetRuleViolations()
{
yield break;
}
partial void OnValidate(ChangeAction action)
{
if (!IsValid)
throw new ApplicationException("Rule violations prevent saving");
}
}
public partial class Bar
{
public bool IsValid
{
get { return (GetRuleViolations().Count() == 0); }
}
public IEnumerable<RuleViolation> GetRuleViolations()
{
yield break;
}
partial void OnValidate(ChangeAction action)
{
if (!IsValid)
throw new ApplicationException("Rule violations prevent saving");
}
}
我想将此功能考虑在内以消除冗余逻辑。我尝试使用IModel接口,然后使用扩展方法进行合同,但它与部分类分解。
我最终得到了这个:
public class ModelBase
{
public bool IsValid
{
get
{
return this.GetRuleViolations().Count() == 0;
}
}
public void OnValidate(ChangeAction action)
{
if (!IsValid) throw new ApplicationException("Rule violations prevent saving");
}
public virtual IEnumerable<RuleViolation> GetRuleViolations() { return null; }
}
public partial class Blog : ModelBase
{
partial void OnValidate(ChangeAction action)
{
base.OnValidate(action);
}
public override IEnumerable<RuleViolation> GetRuleViolations()
{
// rules omitted
}
}
我应该这样做吗?谢谢。
答案 0 :(得分:1)
我唯一要补充的是你可能想要定义一个接口,然后是实现接口的各种基类来提供一些默认验证。例如,您可能有一个基类,它对字符串属性进行XSS验证,验证它们不包含任何HTML。使用接口将允许您从任何这些基类派生(或者甚至只是接口,如果您需要),并且仍然能够将它们视为接口。您可能还考虑使用允许指定ChangeAction的签名 - 您可能对Delete有不同的验证规则而不是Update或Insert。
public interface IValidatedEntity
{
IEnumerable<RuleViolations> GetRuleViolations();
IEnumerable<RuleViolations> GetRuleViolations( ChangeAction action );
}
public abstract class XSSValidatedEntity : IValidatedEntity
{
public virtual IEnumerable<RuleViolations> GetRuleViolations()
{
return GetRuleViolations( ChangeAction.Insert );
}
public virtual IEnumerable<RuleViolations> GetRuleViolations( ChangeAction action )
{
if (action != ChangeAction.Delete)
{
return ValidateStringProperties();
}
return new List<RuleViolations>();
}
}