Использование атрибутов для нормализации и валидации бизнес-сущностей Страница 6. Базовый класс для атрибутов валидации
|
Страница 6 из 6
А теперь напишем аналогичный базовый класс для атрибутов валидации. /// <summary>
/// Базовый класс-атрибут для создания атрибутов валидации
/// </summary>
[AttributeUsage(AttributeTargets.Property)] public abstract class ValidationBaseAttribute : Attribute {
int m_validationOrder = 0; /// <summary>
/// Порядок проведения валидации
/// </summary>
public virtual int ValidationOrder { get {return m_validationOrder;} }
WarningLevel m_level = WarningLevel.Warning; /// <summary>
/// Уровень предупреждения
/// </summary>
public virtual WarningLevel Level { get {return m_level;} set {m_level = value;} }
/// <summary>
/// Базовый атрибут валидации
/// </summary>
/// <param name="validationOrder">Порядковый номер в процессе валидации</param>
public ValidationBaseAttribute(int validationOrder) { m_validationOrder = validationOrder; }
/// <summary>
/// Произвести валидацию
/// </summary>
/// <param name="value">значение для проверки</param>
/// <returns>Строку с предупреждением, либо пустую строку если всё в порядке</returns>
public virtual string Validate(object value) { return "#ValidationBase - Validate method not overrided!"; } } также напишем сортировщик (по аналогии с нормализацией) и несколько атрибутов валидации (их код можно найти в прилагаемом архиве) - ValidationEmptyAttribute (Атрибут проверки свойства на пустоту (null, DBNull, string.empty, (int)0))
- ValidationStringLengthAttribute (Атрибут проверки свойства на длину строки (может применяться несколько раз))
- ValidationIntValueAttribute (Атрибут проверки свойства на значение целочисленного типа (может применяться несколько раз))
- ValidationCollectionEmptyAttribute (Атрибут проверки свойства на пустоту коллекции (списка))
- ValidationDateYearRangeAttribute (Атрибут проверки свойства на нахождение года даты в указанных пределах (может применяться несколько раз))
Напишем достаточно несложный код проверки. Он получает список всех свойств объекта, для каждого свойства запрашивается список атрибутов, дочерних для ValidationBaseAttribute. Затем вызывается виртуальный (переопределенный в дочерних классах) метод Validate который возвращает пустую строку, если предупреждений не было или строку сообщения в противном случае. Полученную строку сообщения мы добавляем в словарь (Hashtable) /// <summary>
/// Проверить объект на соответствие установленным ограничениям
/// </summary>
/// <returns>Словарь найденных несоответствий</returns>
public IDictionary Validate() { IDictionary result = new Hashtable();
PropertyInfo[] pInfo = this.GetType().GetProperties();
for (int j=0; j<pInfo.Length; j++) { Attribute[] atts = Attribute.GetCustomAttributes(pInfo[j], typeof(ValidationBaseAttribute)); if (atts.Length == 0) continue;
Array.Sort(atts, new ValidationComparer()); string _fieldName = pInfo[j].Name; Attribute dna = Attribute.GetCustomAttribute(pInfo[j], typeof(DisplayNameAttribute)); if (dna != null) _fieldName = ((DisplayNameAttribute)dna).Name;
for (int k=0; k<atts.Length; k++) { ValidationBaseAttribute att = (ValidationBaseAttribute)atts[k]; if (att != null) { string vr = att.Validate(pInfo[j].GetValue(this, null)); if (vr != "") { result.Add(_fieldName +": "+ vr, att.Level);
if (att.Level == WarningLevel.Error) break; } } } }
return result; } В строчке //additional можно добавить вызовы собственных, комплексных функций проверки введенных данных, определенных в этом же классе. Словарь возвращенных предупреждений мы выводим в диалоговом окне в виде списка, чтобы пользователь мог с ними ознакомиться (или в данном случае в консоль). и результаты выполнения следующего кода /// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread] static void Main(string[] args) { Person p = new Person(-1); p.ShowNames(); Console.ReadLine();
p.Name = " Иванов Иван Иванович "; Console.WriteLine("'{0}'", p.Name); p.Normalize(); Console.WriteLine("'{0}'", p.Name); Console.ReadLine();
<b>p.Validate();</b> Console.ReadLine(); } Итак, несмотря на некоторые недостатки, данный подход имеет право на существование. |