CSLA.NET 6.0.0
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
CascadeRoot.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Threading.Tasks;
6using Csla.Core;
7using Csla.Rules;
9
11{
12 public class CascadeRoot : BusinessBase<CascadeRoot>
13 {
14 public void CheckRules()
15 {
16 }
17
18 public static readonly PropertyInfo<int> Num1Property = RegisterProperty<int>(c => c.Num1);
19 public int Num1
20 {
21 get { return GetProperty(Num1Property); }
22 set { SetProperty(Num1Property, value); }
23 }
24
25 public static readonly PropertyInfo<int> Num2Property = RegisterProperty<int>(c => c.Num2);
26 public int Num2
27 {
28 get { return GetProperty(Num2Property); }
29 set { SetProperty(Num2Property, value); }
30 }
31
32 public static readonly PropertyInfo<int> Num3Property = RegisterProperty<int>(c => c.Num3);
33 public int Num3
34 {
35 get { return GetProperty(Num3Property); }
36 set { SetProperty(Num3Property, value); }
37 }
38
39 public static readonly PropertyInfo<int> Num4Property = RegisterProperty<int>(c => c.Num4);
40 public int Num4
41 {
42 get { return GetProperty(Num4Property); }
43 set { SetProperty(Num4Property, value); }
44 }
45
46 public static readonly PropertyInfo<int> Num5Property = RegisterProperty<int>(c => c.Num5);
47 public int Num5
48 {
49 get { return GetProperty(Num5Property); }
50 set { SetProperty(Num5Property, value); }
51 }
52
53 internal static PropertyInfo<int> ValueAaProperty = RegisterProperty<int>(c => c.ValueAa);
54 public int ValueAa
55 {
56 get { return GetProperty(ValueAaProperty); }
57 set { SetProperty(ValueAaProperty, value); }
58 }
59
60 internal static PropertyInfo<int> ValueAbProperty = RegisterProperty<int>(c => c.ValueAb);
61 public int ValueAb
62 {
63 get { return GetProperty(ValueAbProperty); }
64 set { SetProperty(ValueAbProperty, value); }
65 }
66
67 internal static PropertyInfo<int> ValueAcProperty = RegisterProperty<int>(c => c.ValueAc);
68 public int ValueAc
69 {
70 get { return GetProperty(ValueAcProperty); }
71 set { SetProperty(ValueAcProperty, value); }
72 }
73
74 internal static PropertyInfo<int> ValueAdProperty = RegisterProperty<int>(c => c.ValueAd);
75 public int ValueAd
76 {
77 get { return GetProperty(ValueAdProperty); }
78 set { SetProperty(ValueAdProperty, value); }
79 }
80
81 internal static PropertyInfo<int> ValueAeProperty = RegisterProperty<int>(c => c.ValueAe);
82 public int ValueAe
83 {
84 get { return GetProperty(ValueAeProperty); }
85 set { SetProperty(ValueAeProperty, value); }
86 }
87
88 internal static PropertyInfo<int> ValueAfProperty = RegisterProperty<int>(c => c.ValueAf);
89 public int ValueAf
90 {
91 get { return GetProperty(ValueAfProperty); }
92 set { SetProperty(ValueAfProperty, value); }
93 }
94
95 internal static PropertyInfo<int> ValueAgProperty = RegisterProperty<int>(c => c.ValueAg);
96 public int ValueAg
97 {
98 get { return GetProperty(ValueAgProperty); }
99 set { SetProperty(ValueAgProperty, value); }
100 }
101
102 internal static PropertyInfo<int> ValueBaProperty = RegisterProperty<int>(c => c.ValueBa);
103 public int ValueBa
104 {
105 get { return GetProperty(ValueBaProperty); }
106 set { SetProperty(ValueBaProperty, value); }
107 }
108
109 internal static PropertyInfo<int> ValueBbProperty = RegisterProperty<int>(c => c.ValueBb);
110 public int ValueBb
111 {
112 get { return GetProperty(ValueBbProperty); }
113 set { SetProperty(ValueBbProperty, value); }
114 }
115
116 internal static PropertyInfo<decimal> ValueCaProperty = RegisterProperty<decimal>(c => c.ValueCa);
117 public decimal ValueCa
118 {
119 get { return GetProperty(ValueCaProperty); }
120 set { SetProperty(ValueCaProperty, value); }
121 }
122
123 internal static PropertyInfo<decimal> ValueCbProperty = RegisterProperty<decimal>(c => c.ValueCb);
124 public decimal ValueCb
125 {
126 get { return GetProperty(ValueCbProperty); }
127 set { SetProperty(ValueCbProperty, value); }
128 }
129
130 internal static PropertyInfo<decimal> ValueCcProperty = RegisterProperty<decimal>(c => c.ValueCc);
131 public decimal ValueCc
132 {
133 get { return GetProperty(ValueCcProperty); }
134 set { SetProperty(ValueCcProperty, value); }
135 }
136
137 internal static PropertyInfo<decimal> ValueCdProperty = RegisterProperty<decimal>(c => c.ValueCd);
138 public decimal ValueCd
139 {
140 get { return GetProperty(ValueCdProperty); }
141 set { SetProperty(ValueCdProperty, value); }
142 }
143
144 internal static PropertyInfo<decimal> ValueCeProperty = RegisterProperty<decimal>(c => c.ValueCe);
145 public decimal ValueCe
146 {
147 get { return GetProperty(ValueCeProperty); }
148 set { SetProperty(ValueCeProperty, value); }
149 }
150
151 protected override void AddBusinessRules()
152 {
153 base.AddBusinessRules();
154
158 BusinessRules.AddRule(new IncrementNotAffected(Num4Property, Num5Property));
159
160 // complex ruleset
161 // calculate the sum of Aa and Ab to Ac
162 // copy value of Ac to Ae
163 // calculate sum of Ad and Ae to Af
164 // copy value of Af to Ag
165 BusinessRules.AddRule(new CalcSumRule(ValueAcProperty, ValueAaProperty, ValueAbProperty) { Priority = -1 });
166 BusinessRules.AddRule(new CopyValueRule(ValueAeProperty, ValueAcProperty));
167 BusinessRules.AddRule(new CalcSumRule(ValueAfProperty, ValueAdProperty, ValueAeProperty) { Priority = -1 });
168 BusinessRules.AddRule(new CopyValueRule(ValueAgProperty, ValueAfProperty));
169
170 // check that the sum of Ba and Bb is always 100 (and error message on both properties)
171 BusinessRules.AddRule(new CheckSumRule(ValueBaProperty, ValueBbProperty, 100));
172 BusinessRules.AddRule(new CheckSumRule(ValueBbProperty, ValueBaProperty, 100));
173
174 // calculate sum of Ca, Cb, Cc and Cd to Ce
175 // calculate fraction of Ce to Cd
176 // must then recalculate sum again as Cd was changed.
177 BusinessRules.AddRule(new CalcSumRule(ValueCeProperty, ValueCaProperty, ValueCbProperty, ValueCcProperty, ValueCdProperty));
178 BusinessRules.AddRule(new CalculateFractionRule(ValueCdProperty, ValueCeProperty, 0.25m));
179 }
181 {
184 }
185
186 [Create]
187 private void Create()
188 {
190 }
191 }
192
193 internal class CheckSumRule : CommonBusinessRule
194 {
195 private readonly int _sumValue;
196 private readonly PropertyInfo<int> _value1Property;
197 private readonly PropertyInfo<int> _value2Property;
198 public CheckSumRule(PropertyInfo<int> value1Property, PropertyInfo<int> value2Property, int sumValue)
199 : base(value1Property)
200 {
201 _sumValue = sumValue;
202 InputProperties.Add(value1Property);
203 InputProperties.Add(value2Property);
204
205 _value1Property = value1Property;
206 _value2Property = value2Property;
207
208 RuleUri.AddQueryParameter("sumvalue", sumValue.ToString());
209 }
210
211 protected override string GetMessage()
212 {
213 return HasMessageDelegate ? base.MessageText : "The sum of {0} and {1} must be equal to {2}.";
214 }
215
216 protected override void Execute(IRuleContext context)
217 {
218 var value1 = context.GetInputValue(_value1Property);
219 var value2 = context.GetInputValue(_value2Property);
220 if (value1 + value2 != _sumValue)
221 {
222 var message = string.Format(GetMessage(), PrimaryProperty.FriendlyName, _value2Property.FriendlyName, _sumValue);
223 context.Results.Add(new RuleResult(RuleName, PrimaryProperty, message) { Severity = Severity });
224 }
225 }
226 }
227
228
229 internal class Increment : Csla.Rules.BusinessRule
230 {
231 private readonly PropertyInfo<int> _primaryProperty;
232 private readonly PropertyInfo<int> _affectedProperty;
233
234 public Increment(PropertyInfo<int> primaryProperty, PropertyInfo<int> affectedProperty) : base(primaryProperty)
235 {
236 _primaryProperty = primaryProperty;
237 _affectedProperty = affectedProperty;
238 if (InputProperties == null) InputProperties = new List<IPropertyInfo>();
239 InputProperties.Add(primaryProperty);
240 AffectedProperties.Add(affectedProperty);
241 }
242
243 protected override void Execute(IRuleContext context)
244 {
245 var val = context.GetInputValue(_primaryProperty);
246 context.AddOutValue(_affectedProperty, val + 1);
247 }
248 }
249
250 internal class CopyValueRule : CommonBusinessRule
251 {
252 private readonly PropertyInfo<int> _sourceProperty;
253
254 public CopyValueRule(PropertyInfo<int> targetProperty, PropertyInfo<int> sourceProperty)
255 : base(targetProperty)
256 {
257 InputProperties.Add(sourceProperty);
258 _sourceProperty = sourceProperty;
259 }
260
261 protected override void Execute(IRuleContext context)
262 {
263 var source = context.GetInputValue(_sourceProperty);
264 context.AddOutValue(source);
265 }
266 }
267
269 {
270 private readonly decimal _fraction;
271 private readonly PropertyInfo<decimal> _sourceProperty;
272
273 public CalculateFractionRule(PropertyInfo<decimal> targetProperty, PropertyInfo<decimal> sourceProperty, decimal fraction)
274 : base(targetProperty)
275 {
276 InputProperties.Add(sourceProperty);
277
278 _sourceProperty = sourceProperty;
279 _fraction = fraction;
280
281 RuleUri.AddQueryParameter("fraction", fraction.ToString());
282 }
283
284 protected override void Execute(IRuleContext context)
285 {
286 var source = context.GetInputValue(_sourceProperty);
287 context.AddOutValue(Math.Round(source * _fraction, 2, MidpointRounding.AwayFromZero));
288 }
289 }
290
292 {
298 public CalcSumRule(IPropertyInfo primaryProperty, params IPropertyInfo[] inputProperties)
299 : base(primaryProperty)
300 {
301 InputProperties = new List<IPropertyInfo>();
302 InputProperties.AddRange(inputProperties);
303 }
304
309 protected override void Execute(IRuleContext context)
310 {
311 // Use linq Sum to calculate the sum value
312 dynamic sum = context.InputPropertyValues.Aggregate<KeyValuePair<IPropertyInfo, object>, dynamic>(0, (current, item) => current + (dynamic)item.Value);
313
314 // add calculated value to OutValues
315 // When rule is completed the RuleEngine will update businessobject
316 context.AddOutValue(PrimaryProperty, sum);
317 }
318 }
319
320 internal class IncrementNotAffected : Csla.Rules.CommonRules.CommonBusinessRule
321 {
322 private readonly PropertyInfo<int> _primaryProperty;
323 private readonly PropertyInfo<int> _affectedProperty;
324
325 public IncrementNotAffected(PropertyInfo<int> primaryProperty, PropertyInfo<int> affectedProperty)
326 : base(primaryProperty)
327 {
328 _primaryProperty = primaryProperty;
329 _affectedProperty = affectedProperty;
330 if (InputProperties == null) InputProperties = new List<IPropertyInfo>();
331 InputProperties.Add(primaryProperty);
332 AffectedProperties.Add(affectedProperty);
333
334 this.CanRunAsAffectedProperty = false;
335 }
336
337 protected override void Execute(IRuleContext context)
338 {
339 var val = context.GetInputValue(_primaryProperty);
340 context.AddOutValue(_affectedProperty, val + 1);
341 }
342 }
343}
This is the base class from which most business objects will be derived.
Definition: BusinessBase.cs:38
Maintains metadata about a property.
virtual Csla.Core.IPropertyInfo PrimaryProperty
Gets or sets the primary property affected by this rule.
List< Csla.Core.IPropertyInfo > InputProperties
Gets a list of secondary property values to be supplied to the rule when it is executed.
List< Csla.Core.IPropertyInfo > AffectedProperties
Gets a list of properties affected by this rule.
Base class used to create business and validation rules.
Definition: BusinessRule.cs:15
Tracks the business rules for a business object.
List< string > CheckRules()
Invokes all rules for the business type.
bool CascadeOnDirtyProperties
Gets or sets a value indicating whether rule engine should cacade n-leves when property value is chan...
void AddRule(IBusinessRuleBase rule)
Associates a business rule with the business object.
Base class used to create common rules.
Definition: CommonRules.cs:21
RuleSeverity Severity
Gets or sets the severity for this rule.
Definition: CommonRules.cs:25
Base class for a property rule
Definition: PropertyRule.cs:17
Contains information about the result of a rule.
Definition: RuleResult.cs:20
Parses a rule:// URI to provide easy access to the parts of the URI.
Definition: RuleUri.cs:19
void AddQueryParameter(string key, string value)
Adds a query parameter to the URI.
Definition: RuleUri.cs:113
override void Execute(IRuleContext context)
Business or validation rule implementation.
Definition: CascadeRoot.cs:309
CalcSumRule(IPropertyInfo primaryProperty, params IPropertyInfo[] inputProperties)
Initializes a new instance of the CalcSumRule class.
Definition: CascadeRoot.cs:298
override void Execute(IRuleContext context)
Business or validation rule implementation.
Definition: CascadeRoot.cs:284
CalculateFractionRule(PropertyInfo< decimal > targetProperty, PropertyInfo< decimal > sourceProperty, decimal fraction)
Definition: CascadeRoot.cs:273
static readonly PropertyInfo< int > Num2Property
Definition: CascadeRoot.cs:25
static readonly PropertyInfo< int > Num3Property
Definition: CascadeRoot.cs:32
static readonly PropertyInfo< int > Num1Property
Definition: CascadeRoot.cs:18
static readonly PropertyInfo< int > Num5Property
Definition: CascadeRoot.cs:46
static readonly PropertyInfo< int > Num4Property
Definition: CascadeRoot.cs:39
Maintains metadata about a property.
string FriendlyName
Gets the friendly display name for the property.
Context information provided to a business rule when it is invoked.
Definition: IRuleContext.cs:22
List< RuleResult > Results
Gets a list of RuleResult objects containing the results of the rule.
Definition: IRuleContext.cs:54
void AddOutValue(object value)
Add an outbound value to update the rule's primary property on the business object once the rule is c...
Dictionary< Csla.Core.IPropertyInfo, object > InputPropertyValues
Gets a dictionary containing copies of property values from the target business object.
Definition: IRuleContext.cs:37
@ Execute
Execute operation.