I have an IEntity interface that implements an interface, IValidatable
public interface IValidatable {
bool IsValid { get; }
bool IsValidForPersistence { get; }
// Rules applied at UI time (please enter your name, etc)
IEnumerable<RuleViolation> GetRuleViolations();
// Rules to be applied only at persistence time
IEnumerable<RuleViolation> GetPersistenceRuleViolations();
}
public interface IEntity : IValidatable {
int ID { get; set; }
}
and for convenience sake I've implemented my Entity class like:
public abstract class Entity : IEntity {
public virtual int ID { get; set; }
public virtual bool IsValid {
get { return RuleViolations().Count() == 0; }
}
public virtual bool IsValidForPersistence {
get { return PersistenceRuleViolations().Count() == 0; }
}
public virtual IEnumerable<RuleViolation> GetRuleViolations() {
return new List<RuleViolation>();
}
public virtual IEnumerable<RuleViolation> GetPersistenceRuleViolations() {
return new List<RuleViolation>();
}
}
By default entities are valid, until GetRuleViolations() or GetPersistenceRuleViolations() are overridden.
public partial class Company {
public override IEnumerable<RuleViolation> GetRuleViolations() {
if (String.IsNullOrEmpty(CompanyName))
yield return new RuleViolation("CompanyName", "Name is required.");
}
public override IEnumerable<RuleViolation> GetPersistenceRuleViolations() {
// Include standard rules too
foreach (RuleViolation rule in RuleViolations) {
yield return rule;
}
// Check some data based on a referenced entity "Bid"
if (!Active && Bid.Active)
yield return new RuleViolation("Active",
"When Active is set to false, the Bid must also be inactive.");
}
}
I know this is a bit naive for validation, so besides any typos, what can be improved?