Commit for development environment setup
This commit is contained in:
@@ -0,0 +1,768 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Csla.Validation
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Tracks the business rules broken within a business object.
|
||||
/// </summary>
|
||||
[Serializable()]
|
||||
public class ValidationRules
|
||||
{
|
||||
// list of broken rules for this business object.
|
||||
private BrokenRulesCollection _brokenRules;
|
||||
// threshold for short-circuiting to kick in
|
||||
private int _processThroughPriority;
|
||||
// reference to current business object
|
||||
[NonSerialized()]
|
||||
private object _target;
|
||||
// reference to per-instance rules manager for this object
|
||||
[NonSerialized()]
|
||||
private ValidationRulesManager _instanceRules;
|
||||
// reference to per-type rules manager for this object
|
||||
[NonSerialized()]
|
||||
private ValidationRulesManager _typeRules;
|
||||
// reference to the active set of rules for this object
|
||||
[NonSerialized()]
|
||||
private ValidationRulesManager _rulesToCheck;
|
||||
|
||||
internal ValidationRules(object businessObject)
|
||||
{
|
||||
SetTarget(businessObject);
|
||||
}
|
||||
|
||||
internal void SetTarget(object businessObject)
|
||||
{
|
||||
_target = businessObject;
|
||||
}
|
||||
|
||||
private BrokenRulesCollection BrokenRulesList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_brokenRules == null)
|
||||
_brokenRules = new BrokenRulesCollection();
|
||||
return _brokenRules;
|
||||
}
|
||||
}
|
||||
|
||||
private ValidationRulesManager GetInstanceRules(bool createObject)
|
||||
{
|
||||
if (_instanceRules == null)
|
||||
if (createObject)
|
||||
_instanceRules = new ValidationRulesManager();
|
||||
return _instanceRules;
|
||||
}
|
||||
|
||||
private ValidationRulesManager GetTypeRules(bool createObject)
|
||||
{
|
||||
if (_typeRules == null)
|
||||
_typeRules = SharedValidationRules.GetManager(_target.GetType(), createObject);
|
||||
return _typeRules;
|
||||
}
|
||||
|
||||
private ValidationRulesManager RulesToCheck
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_rulesToCheck == null)
|
||||
{
|
||||
ValidationRulesManager instanceRules = GetInstanceRules(false);
|
||||
ValidationRulesManager typeRules = GetTypeRules(false);
|
||||
if (instanceRules == null)
|
||||
{
|
||||
if (typeRules == null)
|
||||
_rulesToCheck = null;
|
||||
else
|
||||
_rulesToCheck = typeRules;
|
||||
}
|
||||
else if (typeRules == null)
|
||||
_rulesToCheck = instanceRules;
|
||||
else
|
||||
{
|
||||
// both have values - consolidate into instance rules
|
||||
_rulesToCheck = instanceRules;
|
||||
foreach (KeyValuePair<string, RulesList> de in typeRules.RulesDictionary)
|
||||
{
|
||||
RulesList rules = _rulesToCheck.GetRulesForProperty(de.Key, true);
|
||||
List<IRuleMethod> instanceList = rules.GetList(false);
|
||||
instanceList.AddRange(de.Value.GetList(false));
|
||||
List<string> dependancy = de.Value.GetDependancyList(false);
|
||||
if (dependancy != null)
|
||||
rules.GetDependancyList(true).AddRange(dependancy);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _rulesToCheck;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an array containing the text descriptions of all
|
||||
/// validation rules associated with this object.
|
||||
/// </summary>
|
||||
/// <returns>String array.</returns>
|
||||
/// <remarks></remarks>
|
||||
public string[] GetRuleDescriptions()
|
||||
{
|
||||
List<string> result = new List<string>();
|
||||
ValidationRulesManager rules = RulesToCheck;
|
||||
if (rules != null)
|
||||
{
|
||||
foreach (KeyValuePair<string, RulesList> de in rules.RulesDictionary)
|
||||
{
|
||||
List<IRuleMethod> list = de.Value.GetList(false);
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
IRuleMethod rule = list[i];
|
||||
result.Add(rule.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
#region Short-Circuiting
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the priority through which
|
||||
/// CheckRules should process before short-circuiting
|
||||
/// processing on broken rules.
|
||||
/// </summary>
|
||||
/// <value>Defaults to 0.</value>
|
||||
/// <remarks>
|
||||
/// All rules for each property are processed by CheckRules
|
||||
/// though this priority. Rules with lower priorities are
|
||||
/// only processed if no previous rule has been marked as
|
||||
/// broken.
|
||||
/// </remarks>
|
||||
public int ProcessThroughPriority
|
||||
{
|
||||
get { return _processThroughPriority; }
|
||||
set { _processThroughPriority = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Adding Instance Rules
|
||||
|
||||
/// <summary>
|
||||
/// Adds a rule to the list of rules to be enforced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// A rule is implemented by a method which conforms to the
|
||||
/// method signature defined by the RuleHandler delegate.
|
||||
/// </para><para>
|
||||
/// The propertyName may be used by the method that implements the rule
|
||||
/// in order to retrieve the value to be validated. If the rule
|
||||
/// implementation is inside the target object then it probably has
|
||||
/// direct access to all data. However, if the rule implementation
|
||||
/// is outside the target object then it will need to use reflection
|
||||
/// or CallByName to dynamically invoke this property to retrieve
|
||||
/// the value to be validated.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="handler">The method that implements the rule.</param>
|
||||
/// <param name="propertyName">
|
||||
/// The property name on the target object where the rule implementation can retrieve
|
||||
/// the value to be validated.
|
||||
/// </param>
|
||||
public void AddInstanceRule(RuleHandler handler, string propertyName)
|
||||
{
|
||||
GetInstanceRules(true).AddRule(handler, new RuleArgs(propertyName), 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a rule to the list of rules to be enforced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// A rule is implemented by a method which conforms to the
|
||||
/// method signature defined by the RuleHandler delegate.
|
||||
/// </para><para>
|
||||
/// The propertyName may be used by the method that implements the rule
|
||||
/// in order to retrieve the value to be validated. If the rule
|
||||
/// implementation is inside the target object then it probably has
|
||||
/// direct access to all data. However, if the rule implementation
|
||||
/// is outside the target object then it will need to use reflection
|
||||
/// or CallByName to dynamically invoke this property to retrieve
|
||||
/// the value to be validated.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="handler">The method that implements the rule.</param>
|
||||
/// <param name="propertyName">
|
||||
/// The property name on the target object where the rule implementation can retrieve
|
||||
/// the value to be validated.
|
||||
/// </param>
|
||||
/// <param name="priority">
|
||||
/// The priority of the rule, where lower numbers are processed first.
|
||||
/// </param>
|
||||
public void AddInstanceRule(RuleHandler handler, string propertyName, int priority)
|
||||
{
|
||||
GetInstanceRules(true).AddRule(handler, new RuleArgs(propertyName), priority);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a rule to the list of rules to be enforced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// A rule is implemented by a method which conforms to the
|
||||
/// method signature defined by the RuleHandler delegate.
|
||||
/// </para><para>
|
||||
/// The propertyName may be used by the method that implements the rule
|
||||
/// in order to retrieve the value to be validated. If the rule
|
||||
/// implementation is inside the target object then it probably has
|
||||
/// direct access to all data. However, if the rule implementation
|
||||
/// is outside the target object then it will need to use reflection
|
||||
/// or CallByName to dynamically invoke this property to retrieve
|
||||
/// the value to be validated.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="handler">The method that implements the rule.</param>
|
||||
/// <param name="propertyName">
|
||||
/// The property name on the target object where the rule implementation can retrieve
|
||||
/// the value to be validated.
|
||||
/// </param>
|
||||
/// <typeparam name="T">Type of the business object to be validated.</typeparam>
|
||||
public void AddInstanceRule<T>(RuleHandler<T, RuleArgs> handler, string propertyName)
|
||||
{
|
||||
GetInstanceRules(true).AddRule<T, RuleArgs>(handler, new RuleArgs(propertyName), 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a rule to the list of rules to be enforced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// A rule is implemented by a method which conforms to the
|
||||
/// method signature defined by the RuleHandler delegate.
|
||||
/// </para><para>
|
||||
/// The propertyName may be used by the method that implements the rule
|
||||
/// in order to retrieve the value to be validated. If the rule
|
||||
/// implementation is inside the target object then it probably has
|
||||
/// direct access to all data. However, if the rule implementation
|
||||
/// is outside the target object then it will need to use reflection
|
||||
/// or CallByName to dynamically invoke this property to retrieve
|
||||
/// the value to be validated.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="handler">The method that implements the rule.</param>
|
||||
/// <param name="propertyName">
|
||||
/// The property name on the target object where the rule implementation can retrieve
|
||||
/// the value to be validated.
|
||||
/// </param>
|
||||
/// <param name="priority">
|
||||
/// The priority of the rule, where lower numbers are processed first.
|
||||
/// </param>
|
||||
/// <typeparam name="T">Type of the business object to be validated.</typeparam>
|
||||
public void AddInstanceRule<T>(RuleHandler<T, RuleArgs> handler, string propertyName, int priority)
|
||||
{
|
||||
GetInstanceRules(true).AddRule<T, RuleArgs>(handler, new RuleArgs(propertyName), priority);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a rule to the list of rules to be enforced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A rule is implemented by a method which conforms to the
|
||||
/// method signature defined by the RuleHandler delegate.
|
||||
/// </remarks>
|
||||
/// <param name="handler">The method that implements the rule.</param>
|
||||
/// <param name="args">
|
||||
/// A RuleArgs object specifying the property name and other arguments
|
||||
/// passed to the rule method
|
||||
/// </param>
|
||||
public void AddInstanceRule(RuleHandler handler, RuleArgs args)
|
||||
{
|
||||
GetInstanceRules(true).AddRule(handler, args, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a rule to the list of rules to be enforced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A rule is implemented by a method which conforms to the
|
||||
/// method signature defined by the RuleHandler delegate.
|
||||
/// </remarks>
|
||||
/// <param name="handler">The method that implements the rule.</param>
|
||||
/// <param name="args">
|
||||
/// A RuleArgs object specifying the property name and other arguments
|
||||
/// passed to the rule method
|
||||
/// </param>
|
||||
/// <param name="priority">
|
||||
/// The priority of the rule, where lower numbers are processed first.
|
||||
/// </param>
|
||||
public void AddInstanceRule(RuleHandler handler, RuleArgs args, int priority)
|
||||
{
|
||||
GetInstanceRules(true).AddRule(handler, args, priority);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a rule to the list of rules to be enforced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A rule is implemented by a method which conforms to the
|
||||
/// method signature defined by the RuleHandler delegate.
|
||||
/// </remarks>
|
||||
/// <typeparam name="T">Type of the target object.</typeparam>
|
||||
/// <typeparam name="R">Type of the arguments parameter.</typeparam>
|
||||
/// <param name="handler">The method that implements the rule.</param>
|
||||
/// <param name="args">
|
||||
/// A RuleArgs object specifying the property name and other arguments
|
||||
/// passed to the rule method
|
||||
/// </param>
|
||||
public void AddInstanceRule<T, R>(RuleHandler<T, R> handler, R args) where R : RuleArgs
|
||||
{
|
||||
GetInstanceRules(true).AddRule(handler, args, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a rule to the list of rules to be enforced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A rule is implemented by a method which conforms to the
|
||||
/// method signature defined by the RuleHandler delegate.
|
||||
/// </remarks>
|
||||
/// <typeparam name="T">Type of the target object.</typeparam>
|
||||
/// <typeparam name="R">Type of the arguments parameter.</typeparam>
|
||||
/// <param name="handler">The method that implements the rule.</param>
|
||||
/// <param name="args">
|
||||
/// A RuleArgs object specifying the property name and other arguments
|
||||
/// passed to the rule method
|
||||
/// </param>
|
||||
/// <param name="priority">
|
||||
/// The priority of the rule, where lower numbers are processed first.
|
||||
/// </param>
|
||||
public void AddInstanceRule<T, R>(RuleHandler<T, R> handler, R args, int priority) where R : RuleArgs
|
||||
{
|
||||
GetInstanceRules(true).AddRule(handler, args, priority);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Adding Per-Type Rules
|
||||
|
||||
/// <summary>
|
||||
/// Adds a rule to the list of rules to be enforced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// A rule is implemented by a method which conforms to the
|
||||
/// method signature defined by the RuleHandler delegate.
|
||||
/// </para><para>
|
||||
/// The propertyName may be used by the method that implements the rule
|
||||
/// in order to retrieve the value to be validated. If the rule
|
||||
/// implementation is inside the target object then it probably has
|
||||
/// direct access to all data. However, if the rule implementation
|
||||
/// is outside the target object then it will need to use reflection
|
||||
/// or CallByName to dynamically invoke this property to retrieve
|
||||
/// the value to be validated.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="handler">The method that implements the rule.</param>
|
||||
/// <param name="propertyName">
|
||||
/// The property name on the target object where the rule implementation can retrieve
|
||||
/// the value to be validated.
|
||||
/// </param>
|
||||
public void AddRule(RuleHandler handler, string propertyName)
|
||||
{
|
||||
ValidateHandler(handler);
|
||||
GetTypeRules(true).AddRule(handler, new RuleArgs(propertyName), 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a rule to the list of rules to be enforced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// A rule is implemented by a method which conforms to the
|
||||
/// method signature defined by the RuleHandler delegate.
|
||||
/// </para><para>
|
||||
/// The propertyName may be used by the method that implements the rule
|
||||
/// in order to retrieve the value to be validated. If the rule
|
||||
/// implementation is inside the target object then it probably has
|
||||
/// direct access to all data. However, if the rule implementation
|
||||
/// is outside the target object then it will need to use reflection
|
||||
/// or CallByName to dynamically invoke this property to retrieve
|
||||
/// the value to be validated.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="handler">The method that implements the rule.</param>
|
||||
/// <param name="propertyName">
|
||||
/// The property name on the target object where the rule implementation can retrieve
|
||||
/// the value to be validated.
|
||||
/// </param>
|
||||
/// <param name="priority">
|
||||
/// The priority of the rule, where lower numbers are processed first.
|
||||
/// </param>
|
||||
public void AddRule(RuleHandler handler, string propertyName, int priority)
|
||||
{
|
||||
ValidateHandler(handler);
|
||||
GetTypeRules(true).AddRule(handler, new RuleArgs(propertyName), priority);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a rule to the list of rules to be enforced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// A rule is implemented by a method which conforms to the
|
||||
/// method signature defined by the RuleHandler delegate.
|
||||
/// </para><para>
|
||||
/// The propertyName may be used by the method that implements the rule
|
||||
/// in order to retrieve the value to be validated. If the rule
|
||||
/// implementation is inside the target object then it probably has
|
||||
/// direct access to all data. However, if the rule implementation
|
||||
/// is outside the target object then it will need to use reflection
|
||||
/// or CallByName to dynamically invoke this property to retrieve
|
||||
/// the value to be validated.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="handler">The method that implements the rule.</param>
|
||||
/// <param name="propertyName">
|
||||
/// The property name on the target object where the rule implementation can retrieve
|
||||
/// the value to be validated.
|
||||
/// </param>
|
||||
public void AddRule<T>(RuleHandler<T, RuleArgs> handler, string propertyName)
|
||||
{
|
||||
ValidateHandler(handler);
|
||||
GetTypeRules(true).AddRule<T, RuleArgs>(handler, new RuleArgs(propertyName), 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a rule to the list of rules to be enforced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// A rule is implemented by a method which conforms to the
|
||||
/// method signature defined by the RuleHandler delegate.
|
||||
/// </para><para>
|
||||
/// The propertyName may be used by the method that implements the rule
|
||||
/// in order to retrieve the value to be validated. If the rule
|
||||
/// implementation is inside the target object then it probably has
|
||||
/// direct access to all data. However, if the rule implementation
|
||||
/// is outside the target object then it will need to use reflection
|
||||
/// or CallByName to dynamically invoke this property to retrieve
|
||||
/// the value to be validated.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="handler">The method that implements the rule.</param>
|
||||
/// <param name="propertyName">
|
||||
/// The property name on the target object where the rule implementation can retrieve
|
||||
/// the value to be validated.
|
||||
/// </param>
|
||||
/// <param name="priority">
|
||||
/// The priority of the rule, where lower numbers are processed first.
|
||||
/// </param>
|
||||
public void AddRule<T>(RuleHandler<T, RuleArgs> handler, string propertyName, int priority)
|
||||
{
|
||||
ValidateHandler(handler);
|
||||
GetTypeRules(true).AddRule<T, RuleArgs>(handler, new RuleArgs(propertyName), priority);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a rule to the list of rules to be enforced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A rule is implemented by a method which conforms to the
|
||||
/// method signature defined by the RuleHandler delegate.
|
||||
/// </remarks>
|
||||
/// <param name="handler">The method that implements the rule.</param>
|
||||
/// <param name="args">
|
||||
/// A RuleArgs object specifying the property name and other arguments
|
||||
/// passed to the rule method
|
||||
/// </param>
|
||||
public void AddRule(RuleHandler handler, RuleArgs args)
|
||||
{
|
||||
ValidateHandler(handler);
|
||||
GetTypeRules(true).AddRule(handler, args, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a rule to the list of rules to be enforced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A rule is implemented by a method which conforms to the
|
||||
/// method signature defined by the RuleHandler delegate.
|
||||
/// </remarks>
|
||||
/// <param name="handler">The method that implements the rule.</param>
|
||||
/// <param name="args">
|
||||
/// A RuleArgs object specifying the property name and other arguments
|
||||
/// passed to the rule method
|
||||
/// </param>
|
||||
/// <param name="priority">
|
||||
/// The priority of the rule, where lower numbers are processed first.
|
||||
/// </param>
|
||||
public void AddRule(RuleHandler handler, RuleArgs args, int priority)
|
||||
{
|
||||
ValidateHandler(handler);
|
||||
GetTypeRules(true).AddRule(handler, args, priority);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a rule to the list of rules to be enforced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A rule is implemented by a method which conforms to the
|
||||
/// method signature defined by the RuleHandler delegate.
|
||||
/// </remarks>
|
||||
/// <typeparam name="T">Type of the target object.</typeparam>
|
||||
/// <typeparam name="R">Type of the arguments parameter.</typeparam>
|
||||
/// <param name="handler">The method that implements the rule.</param>
|
||||
/// <param name="args">
|
||||
/// A RuleArgs object specifying the property name and other arguments
|
||||
/// passed to the rule method
|
||||
/// </param>
|
||||
public void AddRule<T, R>(RuleHandler<T, R> handler, R args) where R : RuleArgs
|
||||
{
|
||||
ValidateHandler(handler);
|
||||
GetTypeRules(true).AddRule(handler, args, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a rule to the list of rules to be enforced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A rule is implemented by a method which conforms to the
|
||||
/// method signature defined by the RuleHandler delegate.
|
||||
/// </remarks>
|
||||
/// <typeparam name="T">Type of the target object.</typeparam>
|
||||
/// <typeparam name="R">Type of the arguments parameter.</typeparam>
|
||||
/// <param name="handler">The method that implements the rule.</param>
|
||||
/// <param name="args">
|
||||
/// A RuleArgs object specifying the property name and other arguments
|
||||
/// passed to the rule method
|
||||
/// </param>
|
||||
/// <param name="priority">
|
||||
/// The priority of the rule, where lower numbers are processed first.
|
||||
/// </param>
|
||||
public void AddRule<T, R>(RuleHandler<T, R> handler, R args, int priority) where R : RuleArgs
|
||||
{
|
||||
ValidateHandler(handler);
|
||||
GetTypeRules(true).AddRule(handler, args, priority);
|
||||
}
|
||||
|
||||
private bool ValidateHandler(RuleHandler handler)
|
||||
{
|
||||
return ValidateHandler(handler.Method);
|
||||
}
|
||||
|
||||
private bool ValidateHandler<T, R>(RuleHandler<T, R> handler) where R : RuleArgs
|
||||
{
|
||||
return ValidateHandler(handler.Method);
|
||||
}
|
||||
|
||||
private bool ValidateHandler(System.Reflection.MethodInfo method)
|
||||
{
|
||||
if (!method.IsStatic && method.DeclaringType.Equals(_target.GetType()))
|
||||
throw new InvalidOperationException(
|
||||
string.Format("{0}: {1}",
|
||||
Properties.Resources.InvalidRuleMethodException, method.Name));
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Adding per-type dependancies
|
||||
|
||||
/// <summary>
|
||||
/// Adds a property to the list of dependencies for
|
||||
/// the specified property
|
||||
/// </summary>
|
||||
/// <param name="propertyName">
|
||||
/// The name of the property.
|
||||
/// </param>
|
||||
/// <param name="dependantPropertyName">
|
||||
/// The name of the depandent property.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// When rules are checked for propertyName, they will
|
||||
/// also be checked for any dependant properties associated
|
||||
/// with that property.
|
||||
/// </remarks>
|
||||
public void AddDependantProperty(string propertyName, string dependantPropertyName)
|
||||
{
|
||||
GetTypeRules(true).AddDependantProperty(propertyName, dependantPropertyName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a property to the list of dependencies for
|
||||
/// the specified property
|
||||
/// </summary>
|
||||
/// <param name="propertyName">
|
||||
/// The name of the property.
|
||||
/// </param>
|
||||
/// <param name="dependantPropertyName">
|
||||
/// The name of the depandent property.
|
||||
/// </param>
|
||||
/// <param name="isBidirectional">
|
||||
/// If <see langword="true"/> then a
|
||||
/// reverse dependancy is also established
|
||||
/// from dependantPropertyName to propertyName.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// When rules are checked for propertyName, they will
|
||||
/// also be checked for any dependant properties associated
|
||||
/// with that property. If isBidirectional is
|
||||
/// <see langword="true"/> then an additional association
|
||||
/// is set up so when rules are checked for
|
||||
/// dependantPropertyName the rules for propertyName
|
||||
/// will also be checked.
|
||||
/// </remarks>
|
||||
public void AddDependantProperty(string propertyName, string dependantPropertyName, bool isBidirectional)
|
||||
{
|
||||
|
||||
ValidationRulesManager mgr = GetTypeRules(true);
|
||||
mgr.AddDependantProperty(propertyName, dependantPropertyName);
|
||||
if (isBidirectional)
|
||||
{
|
||||
mgr.AddDependantProperty(dependantPropertyName, propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Checking Rules
|
||||
|
||||
/// <summary>
|
||||
/// Invokes all rule methods associated with
|
||||
/// the specified property and any
|
||||
/// dependant properties.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">The name of the property to validate.</param>
|
||||
public void CheckRules(string propertyName)
|
||||
{
|
||||
// get the rules dictionary
|
||||
ValidationRulesManager rules = RulesToCheck;
|
||||
if (rules != null)
|
||||
{
|
||||
// get the rules list for this property
|
||||
RulesList rulesList = rules.GetRulesForProperty(propertyName, false);
|
||||
if (rulesList != null)
|
||||
{
|
||||
// get the actual list of rules (sorted by priority)
|
||||
List<IRuleMethod> list = rulesList.GetList(true);
|
||||
if (list != null)
|
||||
CheckRules(list);
|
||||
List<string> dependancies = rulesList.GetDependancyList(false);
|
||||
if (dependancies != null)
|
||||
{
|
||||
for (int i = 0; i < dependancies.Count; i++)
|
||||
{
|
||||
string dependantProperty = dependancies[i];
|
||||
CheckRules(rules, dependantProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckRules(ValidationRulesManager rules, string propertyName)
|
||||
{
|
||||
// get the rules list for this property
|
||||
RulesList rulesList = rules.GetRulesForProperty(propertyName, false);
|
||||
if (rulesList != null)
|
||||
{
|
||||
// get the actual list of rules (sorted by priority)
|
||||
List<IRuleMethod> list = rulesList.GetList(true);
|
||||
if (list != null)
|
||||
CheckRules(list);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes all rule methods for all properties
|
||||
/// in the object.
|
||||
/// </summary>
|
||||
public void CheckRules()
|
||||
{
|
||||
ValidationRulesManager rules = RulesToCheck;
|
||||
if (rules != null)
|
||||
{
|
||||
foreach (KeyValuePair<string, RulesList> de in rules.RulesDictionary)
|
||||
CheckRules(de.Value.GetList(true));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given a list
|
||||
/// containing IRuleMethod objects, this
|
||||
/// method executes all those rule methods.
|
||||
/// </summary>
|
||||
private void CheckRules(List<IRuleMethod> list)
|
||||
{
|
||||
bool previousRuleBroken = false;
|
||||
bool shortCircuited = false;
|
||||
|
||||
for (int index = 0; index < list.Count; index++)
|
||||
{
|
||||
IRuleMethod rule = list[index];
|
||||
// see if short-circuiting should kick in
|
||||
if (!shortCircuited && (previousRuleBroken && rule.Priority > _processThroughPriority))
|
||||
shortCircuited = true;
|
||||
|
||||
if (shortCircuited)
|
||||
{
|
||||
// we're short-circuited, so just remove
|
||||
// all remaining broken rule entries
|
||||
BrokenRulesList.Remove(rule);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we're not short-circuited, so check rule
|
||||
if (rule.Invoke(_target))
|
||||
{
|
||||
// the rule is not broken
|
||||
BrokenRulesList.Remove(rule);
|
||||
}
|
||||
else
|
||||
{
|
||||
// the rule is broken
|
||||
BrokenRulesList.Add(rule);
|
||||
if (rule.RuleArgs.Severity == RuleSeverity.Error)
|
||||
previousRuleBroken = true;
|
||||
}
|
||||
if (rule.RuleArgs.StopProcessing)
|
||||
shortCircuited = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Status Retrieval
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether there are any broken rules
|
||||
/// at this time.
|
||||
/// </summary>
|
||||
/// <returns>A value indicating whether any rules are broken.</returns>
|
||||
internal bool IsValid
|
||||
{
|
||||
get { return BrokenRulesList.ErrorCount == 0; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a reference to the readonly collection of broken
|
||||
/// business rules.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The reference returned points to the actual collection object.
|
||||
/// This means that as rules are marked broken or unbroken over time,
|
||||
/// the underlying data will change. Because of this, the UI developer
|
||||
/// can bind a display directly to this collection to get a dynamic
|
||||
/// display of the broken rules at all times.
|
||||
/// </remarks>
|
||||
/// <returns>A reference to the collection of broken rules.</returns>
|
||||
public BrokenRulesCollection GetBrokenRules()
|
||||
{
|
||||
return BrokenRulesList;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user