I have a 'selector' type business rule which chooses which one of 2 inner rules to run dependant on the object state.
The inner rules change the values of multiple properties in the Execute Method e.g.
context.AddOutValue(this.Amount1Property, newAmount1);
context.AddOutValue(this.Amount2Property, newAmount2);
context.AddOutValue(this.Amount3Property, newAmount3);
Workaround now - your inner rule must call
context.Complete();
after it has set the output value or your selector rule must call Complete on the chained context.
OutputPropertyValues is not propagated down into chained RuleContext so your code must call complete in the innermost context.
This may be regarded as a bug - but for optimized memory consumption the OuputPropertyValues dictionary is not created until the first AddOutvalue is called and so the dictionary is not passed on to chained contexts.
If we change the GetChainedContext to
public RuleContext GetChainedContext(IBusinessRule rule)
{
if (OutputPropertyValues == null)
OutputPropertyValues = new Dictionary<Core.IPropertyInfo, object>();
var result = new RuleContext(_completeHandler);
result.Rule = rule;
if (!rule.IsAsync || rule.ProvideTargetWhenAsync)
result.Target = Target;
result.InputPropertyValues = InputPropertyValues;
result.OutputPropertyValues = OutputPropertyValues;
result.Results = Results;
return result;
}
The rules will work as expected out of the box.
Thanks, calling context.Complete() on the inner most rule solved the issue. In fact I added it to a base class of mine so it is called automatically when Execute() competes on a synchronous rule.
[Edit] for anyone else reading this, you also need to make sure the 'selector' rule AffectedProperties contains the inner rule AffectedProperties.
Peran
Copyright (c) Marimer LLC