2009-06-24 5 views
1

У меня есть два класса для этого примера, которые являются частичными классами классов классов LINQ-to-SQL.Есть ли другой способ создать контракт для класса модели 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 
    } 
} 

Должен ли я сделать это по-другому? Спасибо.

ответ

1

Единственное, что я хотел бы добавить к этому, это то, что вы можете определить интерфейс, а затем различные базовые классы, реализующие интерфейс, чтобы обеспечить некоторую проверку по умолчанию. Например, у вас может быть базовый класс, который выполняет XSS-проверку свойств строки, проверяя, что они не содержат HTML. Использование интерфейса позволит вам извлечь из любого из этих базовых классов (или даже просто интерфейс, если хотите) и по-прежнему иметь возможность рассматривать их как интерфейс. Вы также можете подумать о наличии подписи, которая позволяет вам указать ChangeAction - у вас могут быть разные правила проверки для удаления, чем обновление или вставка.

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>(); 
    } 
} 
+0

«у вас могут быть разные правила проверки для удаления, чем обновление или вставка», приятно – blu

 Смежные вопросы

  • Нет связанных вопросов^_^