Hi gents,
Haven't been here for some months which lays testament to how well I'm doing with CSLA 4.2 :)
I need some direction on a business rule that I want to implement.
For simplicity's sake, I basically have a form dialog that accepts several property values of a 'selection' object. This object is a businessbase object, with all of the things you would expect.
The fields are Every, Interval, StartDate, EndDate and NumberServices.
Basically, the user can change ANY of these fields and the bix objects needs to go fire a procedure that returns the other values accordingly.
The problem I have is that to fire any event on any of the changed properties, I assign a rule to the properties ( e.g. .PrimaryProperty=StartDate). The procedure returns new values to the other properties in the class and the propertychanged is raised on those and it becomes a never ending cycle.
There are essentially two issues I need to solve here - 1. to stop to recursive calls (can I somehow shortcircuit the propertychanged) and 2. Is there a way to pass the PropertyName that has changed to my commandbase business rule? (Affects which properties are updated)
Here's what my code looks like:
Protected Overrides Sub AddBusinessRules()
MyBase.AddBusinessRules()
With BusinessRules
.AddRule(New CalculateServiceSeriesRule() With {.PrimaryProperty = EveryProperty})
.AddRule(New CalculateServiceSeriesRule() With {.PrimaryProperty = IntervalProperty})
.AddRule(New CalculateServiceSeriesRule() With {.PrimaryProperty = StartDateProperty})
.AddRule(New CalculateServiceSeriesRule() With {.PrimaryProperty = EndDateProperty})
.AddRule(New CalculateServiceSeriesRule() With {.PrimaryProperty = NumberServicesProperty})
End With
End Sub
and;
Private Class CalculateServiceSeriesRule
Inherits Csla.Rules.BusinessRule
Protected Overrides Sub Execute(context As Csla.Rules.RuleContext)
Dim target = DirectCast(context.Target, ServiceSeriesCreator)
Dim _every As Integer = target.Every
Dim _interval As String = target.Interval
Dim _startdate As SmartDate = target.StartDate
Dim _enddate As SmartDate = target.EndDate
Dim _numberservices As Integer = target.NumberServices
Dim _propertychanged As String = "Every" ' ** would like to pass the propertyname here ***
ServiceSeriesCreator.CalculateServiceSeries( _
_propertychanged _
, _every _
, _interval _
, _startdate _
, _enddate _
, _numberservices _
)
target.StartDate = _startdate
target.EndDate = _enddate
target.NumberServices = _numberservices
End Sub
End Class
Any help would be appreciated.
Thanks,
Graham
I believe I figured out on of the issues;
The propertyname I can derived as:
Dim _propertychanged As String = PrimaryProperty.Name
Curiously, the code appears to be working...
Can I confirm that I do in fact have a recursion issue? If whilst checking a value that has risen a PropertyChanged event, my routine updates other members of that BO, do they automatically get fired? If not, that's great....
Thanks,
Graham
You should never assign a new value to a property by the property setter directly in the Executre method. This triggers new validation rules from inside the Execute method and makes the rules run recursively.
You should rather use context.AddOutValue to update property values.
In your case I would rather:
Thanks Jonny - I'll look into that. is CanRunAsAffectedProperty just a tag of the property constructor?
It is a property on rules that inherit from PropertyRule or CommonRules.CommonBusinessRule (that in turn inherits from PropertyRule).
Copyright (c) Marimer LLC