BusinessRules confusion

BusinessRules confusion

Old forum URL: forums.lhotka.net/forums/t/11250.aspx


jasona22 posted on Thursday, March 22, 2012

I am having a difficult time with a set of business rules.  Last I worked in CSLA Business rules I was in 3.8.  We moved to 4.0 and mostly I use CodeSmith and build the business objects.  However I am helping out with business rules.  So, to the problem.  In 3.8, I recall adding rules to properties and when a rule failed, the BrokenRulesCollection got populated.  In 4.0, it seems to be different.  Specifically, I have a pair of rules that the first one fails but the second succeeds and "hides" the failure of the first. 

Example:

Properties: Date1, Date2, Date3

Date1 Rules: Date1 Required, Date1 LessThan "NOW"

Date2 Rules: Date2 GreaterThan Date1, Date2 LessThan Date3

Date 3 Rules Date3 LessThan "NOW", Date3 GreaterThan Date1

The gist is a flight.  Date1 is the date/time it takes off.  If it lands but doesn't shut down(refuels while running), the takeoff time is Date2 and the landing at its final destination is date3, which means Date2 is not a required value.  This data is captured post flight.  Thus all dates are prior to the current date/time and must be chronological. 

Testing my rules:

3 valid dates I get no broken rules as expected

Change Date2 and make Date2 greater than Date3 and I get a broken rule and it flags on the screen as expected

Change Date2 and make Date2 less than Date 1 and there is no flag on screen.  If I put a breakpoint on my rule, I see the rule fail; however the next rule is Date2 LessThan Date3 and that succeeds so the broken rule seems to be over written with a success.  Back in 3.8, once a rule was broken, it wasn't removed from the collection until its condition was satisfied (other than explictly clearing the collection). 

I cannot find anything in the digital books that helps with this.  The order of the rules is irrelivant as if I set priorieties, then I can fail the rules one way but again not the other.  It probably isn't as hard as it seems, but this is not nearly as easy as 3.8 was.

JonnyBee replied on Thursday, March 22, 2012

Hi,

So you have the same rule with the same primaryProperty but different properties to compare to.

Then you MUST make sure that each rule instance have a unique RuleName.
To achieve this the secondary property must be added to as QueryParameter to the RuleURI.

  public class GreaterThan : CommonBusinessRule
  {
    private IPropertyInfo CompareTo { getset; }

    public GreaterThan(IPropertyInfo primaryProperty, IPropertyInfo compareToProperty)
      : base(primaryProperty)
    {
      CompareTo = compareToProperty;
      InputProperties = new List<IPropertyInfo>() { primaryProperty, compareToProperty };
      this.RuleUri.AddQueryParameter("compareTo", compareToProperty.Name);
    }

Will give this RuleName:   "rule://comparefieldsrules.rules.greaterthan/EndDate?compareTo=StartDate" 
and the result from the two rules will not be viewed as the result of the same rule by the BrokenRulesCollection.

This is also true for CSLA 3.8  - taken from Csla 3.8 : Csla.Validation.IRuleMethod:

    /// <summary>
    /// Gets the name of the rule.
    /// </summary>
    /// <remarks>
    /// The rule's name must be unique and is used
    /// to identify a broken rule in the BrokenRules
    /// collection.
    /// </remarks>
    string RuleName { get;}

jasona22 replied on Thursday, March 22, 2012

YOU ARE THE MAN!  Thank you so much, that worked perfectly.

Copyright (c) Marimer LLC