Adding the following validators:
[castle.git] / Components / General / Validator / Castle.Components.Validator / CachedValidationRegistry.cs
blob0854f726789a65f112e21b29ed47aa08de2664de
1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.Components.Validator
17 using System;
18 using System.Collections;
19 using System.Reflection;
21 /// <summary>
22 /// <see cref="IValidatorRegistry"/> implementation that
23 /// caches the reflection and custom attributes calls for better performance.
24 /// </summary>
25 public class CachedValidationRegistry : IValidatorRegistry
27 private readonly IDictionary propertiesPerType = Hashtable.Synchronized(new Hashtable());
28 private readonly IDictionary attrsPerProperty = Hashtable.Synchronized(new Hashtable());
30 #region IValidatorRegistry Members
32 /// <summary>
33 /// Gets all validators associated with a <see cref="Type"/>.
34 /// <para>
35 /// The validators returned are initialized.
36 /// </para>
37 /// </summary>
38 /// <param name="validatorRunner">The validator runner.</param>
39 /// <param name="targetType">Target type.</param>
40 /// <param name="runWhen">Restrict the set returned to the phase specified</param>
41 /// <returns>A Validator array</returns>
42 public IValidator[] GetValidators(ValidatorRunner validatorRunner, Type targetType, RunWhen runWhen)
44 PropertyInfo[] properties = (PropertyInfo[]) propertiesPerType[targetType];
46 if (properties == null)
48 properties = targetType.GetProperties();
49 propertiesPerType[targetType] = properties;
52 ArrayList list = new ArrayList();
54 foreach(PropertyInfo prop in properties)
56 list.AddRange(GetValidators(validatorRunner, targetType, prop, runWhen));
59 return (IValidator[]) list.ToArray(typeof(IValidator));
62 /// <summary>
63 /// Gets all validators associated with a property.
64 /// <para>
65 /// The validators returned are initialized.
66 /// </para>
67 /// </summary>
68 /// <param name="validatorRunner">The validator runner.</param>
69 /// <param name="targetType">Target type.</param>
70 /// <param name="property">The property.</param>
71 /// <param name="runWhen">Restrict the set returned to the phase specified</param>
72 /// <returns>A Validator array</returns>
73 public IValidator[] GetValidators(ValidatorRunner validatorRunner, Type targetType, PropertyInfo property, RunWhen runWhen)
75 object[] builders = (object[]) attrsPerProperty[property];
77 if (builders == null)
79 builders = property.GetCustomAttributes(typeof(IValidatorBuilder), true);
80 attrsPerProperty[property] = builders;
83 ArrayList validators = new ArrayList();
85 foreach(IValidatorBuilder builder in builders)
87 IValidator validator = builder.Build(validatorRunner, targetType);
89 if (!IsValidatorOnPhase(validator, runWhen)) continue;
91 validator.Initialize(property);
92 validators.Add(validator);
95 return (IValidator[]) validators.ToArray(typeof(IValidator));
98 #endregion
100 private static bool IsValidatorOnPhase(IValidator validator, RunWhen when)
102 if (validator.RunWhen == RunWhen.Everytime) return true;
104 return ((validator.RunWhen & when) != 0);