/Blocks/Validation/Src/Validation/Validators/ObjectCollectionValidator.cs

# · C# · 226 lines · 122 code · 16 blank · 88 comment · 21 complexity · 077f394d36fb7b6b8964d8ea0d59fba7 MD5 · raw file

  1. //===============================================================================
  2. // Microsoft patterns & practices Enterprise Library
  3. // Validation Application Block
  4. //===============================================================================
  5. // Copyright Š Microsoft Corporation. All rights reserved.
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
  7. // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
  8. // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  9. // FITNESS FOR A PARTICULAR PURPOSE.
  10. //===============================================================================
  11. using System;
  12. using System.Collections;
  13. using Microsoft.Practices.EnterpriseLibrary.Validation.Properties;
  14. namespace Microsoft.Practices.EnterpriseLibrary.Validation.Validators
  15. {
  16. /// <summary>
  17. /// Performs validation on collection objects by applying the validation rules specified for a supplied type
  18. /// to its members.
  19. /// </summary>
  20. /// <seealso cref="ValidationFactory"/>
  21. #if !SILVERLIGHT
  22. [Common.Configuration.ConfigurationElementType(typeof(Configuration.ObjectCollectionValidatorData))]
  23. #endif
  24. public class ObjectCollectionValidator : Validator
  25. {
  26. private readonly Type targetType;
  27. private readonly string targetRuleset;
  28. private readonly Validator targetTypeValidator;
  29. private readonly ValidatorFactory validatorFactory;
  30. /// <summary>
  31. /// <para>Initializes a new instance of the <see cref="ObjectCollectionValidator"/>.</para>
  32. /// </summary>
  33. /// <remarks>
  34. /// The default ruleset will be used for validation.
  35. /// </remarks>
  36. public ObjectCollectionValidator()
  37. : this(ValidationFactory.DefaultCompositeValidatorFactory)
  38. { }
  39. /// <summary>
  40. /// <para>Initializes a new instance of the <see cref="ObjectCollectionValidator"/>
  41. /// using the supplied ruleset.</para>
  42. /// </summary>
  43. /// <param name="validatorFactory">Factory to use when building nested validators.</param>
  44. public ObjectCollectionValidator(ValidatorFactory validatorFactory)
  45. : this(validatorFactory, string.Empty)
  46. { }
  47. /// <summary>
  48. /// <para>Initializes a new instance of the <see cref="ObjectCollectionValidator"/>
  49. /// using the supplied ruleset.</para>
  50. /// </summary>
  51. /// <param name="validatorFactory">Factory to use when building nested validators.</param>
  52. /// <param name="targetRuleset">The ruleset to use.</param>
  53. /// <exception cref="ArgumentNullException">when <paramref name="targetRuleset"/> is <see langword="null"/>.</exception>
  54. /// <exception cref="ArgumentNullException">when <paramref name="validatorFactory"/> is <see langword="null"/>.</exception>
  55. public ObjectCollectionValidator(ValidatorFactory validatorFactory, string targetRuleset)
  56. : base(null, null)
  57. {
  58. if (validatorFactory == null)
  59. {
  60. throw new ArgumentNullException("validatorFactory");
  61. }
  62. if (targetRuleset == null)
  63. {
  64. throw new ArgumentNullException("targetRuleset");
  65. }
  66. this.targetType = null;
  67. this.targetTypeValidator = null;
  68. this.targetRuleset = targetRuleset;
  69. this.validatorFactory = validatorFactory;
  70. }
  71. /// <summary>
  72. /// <para>Initializes a new instance of the <see cref="ObjectCollectionValidator"/> for a target type.</para>
  73. /// </summary>
  74. /// <param name="targetType">The target type</param>
  75. /// <remarks>
  76. /// The default ruleset for <paramref name="targetType"/> will be used.
  77. /// </remarks>
  78. /// <exception cref="ArgumentNullException">when <paramref name="targetType"/> is <see langword="null"/>.</exception>
  79. public ObjectCollectionValidator(Type targetType)
  80. : this(targetType, string.Empty)
  81. { }
  82. /// <summary>
  83. /// <para>Initializes a new instance of the <see cref="ObjectCollectionValidator"/> for a target type
  84. /// using the supplied ruleset.</para>
  85. /// </summary>
  86. /// <param name="targetType">The target type</param>
  87. /// <param name="targetRuleset">The ruleset to use.</param>
  88. /// <exception cref="ArgumentNullException">when <paramref name="targetType"/> is <see langword="null"/>.</exception>
  89. /// <exception cref="ArgumentNullException">when <paramref name="targetRuleset"/> is <see langword="null"/>.</exception>
  90. public ObjectCollectionValidator(Type targetType, string targetRuleset)
  91. : this(targetType, ValidationFactory.DefaultCompositeValidatorFactory, targetRuleset)
  92. { }
  93. /// <summary>
  94. /// <para>Initializes a new instance of the <see cref="ObjectCollectionValidator"/> for a target type
  95. /// using the supplied ruleset.</para>
  96. /// </summary>
  97. /// <param name="targetType">The target type</param>
  98. /// <param name="validatorFactory">Factory to use when building nested validators.</param>
  99. /// <param name="targetRuleset">The ruleset to use.</param>
  100. /// <exception cref="ArgumentNullException">when <paramref name="targetType"/> is <see langword="null"/>.</exception>
  101. /// <exception cref="ArgumentNullException">when <paramref name="targetRuleset"/> is <see langword="null"/>.</exception>
  102. /// <exception cref="ArgumentNullException">when <paramref name="validatorFactory"/> is <see langword="null"/>.</exception>
  103. public ObjectCollectionValidator(Type targetType, ValidatorFactory validatorFactory, string targetRuleset)
  104. : base(null, null)
  105. {
  106. if (targetType == null)
  107. {
  108. throw new ArgumentNullException("targetType");
  109. }
  110. if (targetRuleset == null)
  111. {
  112. throw new ArgumentNullException("targetRuleset");
  113. }
  114. if (validatorFactory == null)
  115. {
  116. throw new ArgumentNullException("validatorFactory");
  117. }
  118. this.targetType = targetType;
  119. this.targetTypeValidator = validatorFactory.CreateValidator(targetType, targetRuleset);
  120. this.targetRuleset = targetRuleset;
  121. this.validatorFactory = null;
  122. }
  123. /// <summary>
  124. /// Validates by applying the validation rules for the target type specified for the receiver to the elements
  125. /// in <paramref name="objectToValidate"/>.
  126. /// </summary>
  127. /// <param name="objectToValidate">The object to validate.</param>
  128. /// <param name="currentTarget">The object on the behalf of which the validation is performed.</param>
  129. /// <param name="key">The key that identifies the source of <paramref name="objectToValidate"/>.</param>
  130. /// <param name="validationResults">The validation results to which the outcome of the validation should be stored.</param>
  131. /// <remarks>
  132. /// If <paramref name="objectToValidate"/> is <see langword="null"/> validation is ignored.
  133. /// <para/>
  134. /// A reference to a non collection object causes a validation failure and the validation rules
  135. /// for the configured target type will not be applied.
  136. /// <para/>
  137. /// Elements in the collection of a type not compatible with the configured target type causes a validation failure but
  138. /// do not affect validation on other elements.
  139. /// </remarks>
  140. public override void DoValidate(object objectToValidate,
  141. object currentTarget,
  142. string key,
  143. ValidationResults validationResults)
  144. {
  145. if (objectToValidate != null)
  146. {
  147. IEnumerable enumerable = objectToValidate as IEnumerable;
  148. if (enumerable != null)
  149. {
  150. foreach (object element in enumerable)
  151. {
  152. if (element != null)
  153. {
  154. var elementType = element.GetType();
  155. if (this.targetType == null || this.targetType.IsAssignableFrom(elementType))
  156. {
  157. // reset the current target and the key
  158. this.GetValidator(elementType).DoValidate(element, element, null, validationResults);
  159. }
  160. else
  161. {
  162. // unlikely
  163. this.LogValidationResult(validationResults,
  164. Resources.ObjectCollectionValidatorIncompatibleElementInTargetCollection,
  165. element,
  166. null);
  167. }
  168. }
  169. }
  170. }
  171. else
  172. {
  173. this.LogValidationResult(validationResults, Resources.ObjectCollectionValidatorTargetNotCollection, currentTarget, key);
  174. }
  175. }
  176. }
  177. private Validator GetValidator(Type elementType)
  178. {
  179. if (this.targetTypeValidator != null)
  180. {
  181. return this.targetTypeValidator;
  182. }
  183. else
  184. {
  185. return this.validatorFactory.CreateValidator(elementType, this.targetRuleset);
  186. }
  187. }
  188. /// <summary>
  189. /// Gets the message template to use when logging results no message is supplied.
  190. /// </summary>
  191. protected override string DefaultMessageTemplate
  192. {
  193. get { return null; }
  194. }
  195. /// <summary>
  196. /// Type of target being validated.
  197. /// </summary>
  198. public Type TargetType
  199. {
  200. get { return this.targetType; }
  201. }
  202. /// <summary>
  203. /// Ruleset to use when creating target validators.
  204. /// </summary>
  205. public string TargetRuleset
  206. {
  207. get { return this.targetRuleset; }
  208. }
  209. }
  210. }