Работая с NerdDinner Tutorial , я пытаюсь найти хороший способ выполнить проверку свойств, которые не зависят от сгенерированного частичного класса LINQ-to-SQL. Вот пример кода того, что я сделал до сих пор:
public abstract class DomainEntity
{
public IEnumerable<ValidationError> ValidationErrors { get; private set; }
public bool Validate()
{
bool isValid = false;
if (this.ValidationErrors != null)
this.ValidationErrors = null;
this.ValidationErrors = this.GetValidationErrors();
if (this.ValidationErrors.Count() == 0)
isValid = true;
return isValid;
}
protected abstract IEnumerable<ValidationError> GetValidationErrors();
}
public partial class Email : DomainEntity
{
protected override IEnumerable<ValidationError> GetValidationErrors()
{
if (!this.ValidateAddress())
yield return new ValidationError("Address", DomainResources.EmailAddressValidationErrorMessage);
yield break;
}
partial void OnValidate(ChangeAction action)
{
bool isValid = this.Validate();
if (!isValid)
throw new InvalidEmailException(this);
}
private bool ValidateAddress()
{
// TODO: Use a regex to validate the email address.
return !string.IsNullOrEmpty(this.Address);
}
}
Где Email - это сгенерированный тип LINQ-to-SQL, основанный на таблице Email. Поскольку таблица Email является лишь одним из нескольких объектов, связанных с классом модели домена (скажем, «Пользователь»), идеальным вариантом является создание класса модели домена «Пользователь» и использование атрибутов Application Validation Block для проверить свойства. Другими словами, я хотел бы использовать это:
public class User
{
private Email emailEntity;
[EmailAddressValidator]
public string EmailAddress
{
get { return emailEntity.Address; }
set { emailEntity.Address = value; }
}
}
Так что, если я изменю свою схему базы данных, и эти изменения попадут в мои классы, сгенерированные LINQ-to-SQL, у меня не будет этих потерянных частичных классов (например, частичного класса Email). Я также хочу получить выгоду от интеграции атрибутов блока приложения проверки, чтобы мне не нужно было поддерживать коллекцию регулярных выражений, как это делается в руководстве NerdDinner. Кроме того, пользователь как класс домена будет функциональной единицей в домене, а не электронной почтой и другими объектами, для создания моделей представлений, рендеринга представлений и т. Д. Однако нет способа перехватить вызов проверки без выполнения чего-то вроде:
public abstract class DomainEntity
{
public event EventHandler Validation(object sender, EventArgs args);
protected void OnValidation()
{
if (this.Validate != null)
this.Validate(this, EventArgs.Empty);
}
}
public partial class Email
{
partial void OnValidate(ChangeAction action)
{
this.OnValidation();
}
}
И затем пользователь подключается к этому событию и обрабатывает все проверки внутри пользователя. Будет ли это хорошо работать с блоком приложения проверки? Как правильно выполнять проверку в классах агрегированных доменов, таких как «Пользователь»?