CSLA Version 4.1
Hello !
I have two Properties: one called DeliveryWeek (LieferKW) and one called DeliveryDate (Liefertermin).
Further i have two Rules which calculate a DeliveryDate (Friday of Week) from DeliveryWeek
and one Rule that calculate a DeliveryWeek vom DeliveryDate.
The User must can change both (vice versa) in the WPF UI and the other Field must be updated.
The Problem is, that when the user enter a new DeliveryDate the CalculateLieferterminRule runs first
and reset the DeliveryDate.
What is the right Way to setup the Rules ?
My Code:
protected override void AddBusinessRules()
{
base.AddBusinessRules();
//Some Other Rules for Required Fields
//BusinessRules.AddRule(new Csla.Rules.CommonRules.Dependency(LieferKWProperty, LieferterminProperty));
//BusinessRules.AddRule(new Csla.Rules.CommonRules.Dependency(LieferterminProperty, LieferKWProperty));
BusinessRules.AddRule(new CalculateLieferterminRule(LieferterminProperty, LieferKWProperty){Priority = 1});
BusinessRules.AddRule(new CalculateLieferKWRule(LieferKWProperty, LieferterminProperty) { Priority = 1 });
}
private class CalculateLieferterminRule : BusinessRule
{
private IPropertyInfo LieferKWProperty;
public CalculateLieferterminRule(IPropertyInfo primaryProperty, IPropertyInfo lieferKWProperty) : base(primaryProperty)
{
if (InputProperties == null)
{
InputProperties = new List<IPropertyInfo>() {primaryProperty, lieferKWProperty};
}
PrimaryProperty = primaryProperty;
LieferKWProperty = lieferKWProperty;
AffectedProperties.Add(PrimaryProperty);
}
protected override void Execute(RuleContext context)
{
var lieferKw = Convert.ToInt32(context.InputPropertyValues[LieferKWProperty]);
DateTime? liefertermin = DateTimeExtension.GetLastBusinessDateOfWeek(lieferKw);
context.AddOutValue(PrimaryProperty, liefertermin);
}
}
private class CalculateLieferKWRule : BusinessRule
{
private IPropertyInfo LieferterminProperty;
public CalculateLieferKWRule(IPropertyInfo primaryProperty, IPropertyInfo lieferterminProperty) : base(primaryProperty)
{
if (InputProperties == null)
{
InputProperties = new List<IPropertyInfo>() {primaryProperty, lieferterminProperty};
}
PrimaryProperty = primaryProperty;
LieferterminProperty = lieferterminProperty;
AffectedProperties.Add(PrimaryProperty);
}
protected override void Execute(RuleContext context)
{
var liefertermin = Convert.ToDateTime(context.InputPropertyValues[LieferterminProperty]);
int lieferKW = DateTimeExtension.GetCalendarWeekWithYear(liefertermin);
context.AddOutValue(PrimaryProperty, lieferKW);
}
}
Hi,
First. Remove the dependecy rules. AffectedProperty creates a dependency.
Then rewrite the rules to set the "AffectedProperty" - ie: the CalculateLieferKWRule should have LieferTerminProperty as primary property and LieferKWProperty as Output property/AffectedProperty.
The rule engine will for a given property run the rules
So as your rules is defined now - when LieferterminProperty is changed the rules where LiferterminProperty is primary property will run first and that is the CalculateLieferteminRule.
Hello Jonny,
thank you for your quick answer, it works. I was some Kind of Blind, Naturally must the Primary Property be the Property wich is the source for the calculating.
But for me i have another question with Rules.
What is the best 'CSLA Style' to implement such calculations and what is the effort to make it in Rules ?
I mean, that i also can do this sort of calculation in the setter of the Property.
In the RuleTutorial are a lot of Validation Rules, but not so many Calculation Rules.
Hi Thilo,
In general terms:
Starting from CSLA 4.2 you can also tell the rule engine when NOT to run the rule:
You should also look at my blog posts:
Copyright (c) Marimer LLC