I've created a simple validation process for a small project. The validation rules are created as attributes to properties of a class.
I have a static class that requires to pass the class type. The method will first check if the set of rules for the given class is already in the dictionary, otherwise, it will use reflection to go through each property.
Will there be any issues when using this kind of approach? I'm worrying that it may cause some issues when being accessed in multi-threaded environments.
public static class Validator
{
private static Dictionary<Type, ValidationRulesCollection> _validationRules = new Dictionary<Type, ValidationRulesCollection>();
public static ValidationRulesCollection GetValidationRules(object obj)
{
return GetValidationRules(obj.GetType());
}
public static ValidationRulesCollection GetValidationRules(Type t)
{
ValidationRulesCollection rules = null;
/* Check if the centralized rules repository already contains the rules for this class type */
if (_validationRules.ContainsKey(t) == true)
{
rules = _validationRules[t];
}
else
{
/* Using reflection, get the list of properties for the class type */
PropertyInfo[] properties = t.GetProperties();
if (properties != null)
{
/* Iterate through each property info and check if it contains a validation rule */
ValidationAttribute[] attribs = null;
foreach (PropertyInfo property in properties)
{
/* For each property, check if it contains a validation rule */
attribs = (ValidationAttribute[])property.GetCustomAttributes(typeof(ValidationAttribute), true);
if (attribs != null)
{
foreach (ValidationAttribute attrib in attribs)
{
if (rules == null)
rules = new ValidationRulesCollection();
/* Add the validation rule to the collection */
rules.Add(new ValidationRule(property, attrib));
}
}
}
}
/* Add the rules collection to the centralized rules repository */
if (rules.Count > 0)
_validationRules.Add(t, rules);
else
throw new ArgumentNullException("The type " + t.ToString() + " does not have any ValidationAttributes");
}
return rules;
}
public static ValidationRulesCollection Validate(object obj)
{
/* Get the Validation Rules */
ValidationRulesCollection rules = GetValidationRules(obj);
/* Validate the rules */
foreach (ValidationRule rule in rules)
{
rule.Validate(obj);
}
return rules;
}
}