Есть только одна структура проверки, которую я хорошо знаю, и это Блок приложения проверки корпоративной библиотеки , или VAB для краткости. Я отвечу на ваши вопросы из контекста VAB.
Первый вопрос: Можно ли выполнить проверку состояния (между полями) в VAB?
Да, вы можете. Есть несколько способов сделать это. Вы можете выбрать механизм самопроверки следующим образом:
[HasSelfValidation]
public class Range
{
public int Min { get; set; }
public int Max { get; set; }
[SelfValidation]
public void ValidateRange(ValidationResults results)
{
if (this.Max < this.Min)
{
results.AddResult(
new ValidationResult("Max less than min", this, "", "", null));
}
}
}
Я должен сказать, что лично мне не нравятся проверки этого типа, особенно при проверке сущностей моего домена, потому что мне нравится отделять валидации от логики валидации (и в моей доменной логике не должно быть ссылок на какие-либо рамки валидации) , Однако им требуется значительно меньше кода, чем альтернативе, которая пишет собственный класс валидатора. Вот пример:
[ConfigurationElementType(typeof(CustomValidatorData))]
public sealed class RangeValidator : Validator
{
public RangeValidator(NameValueCollection attributes)
: base(string.Empty, string.Empty) { }
protected override string DefaultMessageTemplate
{
get { throw new NotImplementedException(); }
}
protected override void DoValidate(object objectToValidate,
object currentTarget, string key, ValidationResults results)
{
Range range = (Range)currentTarget;
if (range.Max < range.Min)
{
this.LogValidationResult(results,
"Max less than min", currentTarget, key);
}
}
}
После написания этого класса вы можете подключить этот класс в своем файле конфигурации проверки следующим образом:
<validation>
<type name="Range" defaultRuleset="Default" assemblyName="[Range Assembly]">
<ruleset name="Default">
<validator type="[Namespace].RangeValidator, [Validator Assembly]"
name="Range Validator" />
</ruleset>
</type>
</validation>
Второй вопрос: как проводить сложные проверки с возможным взаимодействием с базой данных (с VAB).
Примеры, которые я привел для первого вопроса, также пригодны для этого. Вы можете использовать те же методы: самопроверка и пользовательский валидатор. Ваш сценарий, в котором вы хотите проверить значение в базе данных, на самом деле прост, потому что валидность вашего объекта не зависит от его контекста. Вы можете просто проверить состояние объекта по базе данных. Это становится более сложным, когда контекст, в котором живет объект, становится важным (но это возможно с VAB). Представьте, например, что вы хотите написать валидацию, которая гарантирует, что у каждого клиента в данный момент времени не более двух отгруженных заказов. Это не только означает, что вы должны проверить базу данных, но, возможно, новые заказы, которые добавляются или заказы удаляются в том же контексте. Эта проблема не специфична для VAB, у вас будут одинаковые проблемы с каждой выбранной вами средой. Я написал статью , в которой описываются сложности, с которыми мы сталкиваемся в этих ситуациях (чтение и дрожь).
Третий вопрос: как вы, люди в реальном мире, справляетесь с этой ситуацией?
Я выполняю эти типы проверки с помощью VAB в рабочем коде. Это прекрасно работает, но VAB не очень прост в освоении. Тем не менее, я люблю то, что мы можем сделать с VAB, и это будет только лучше, когда выйдет v5.0. Если вы хотите изучить его, начните с чтения документа ValidationHOL.pdf, который вы можете найти в практических занятиях .
Надеюсь, это поможет.