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.
RuleContext.cs
Go to the documentation of this file.
1//-----------------------------------------------------------------------
2// <copyright file="RuleContext.cs" company="Marimer LLC">
3// Copyright (c) Marimer LLC. All rights reserved.
4// Website: https://cslanet.com
5// </copyright>
6// <summary>Context information provided to a business rule</summary>
7//-----------------------------------------------------------------------
8using System;
9using System.ComponentModel;
10using System.Collections.Generic;
11using Csla.Core;
12using Csla.Properties;
13using System.Security.Principal;
14using System.Security.Claims;
15
16namespace Csla.Rules
17{
21 [Flags]
22 public enum RuleContextModes
23 {
27 Any = 247,
31 CheckRules = 1,
44 }
45
51 {
55 [EditorBrowsable(EditorBrowsableState.Never)]
56 public IBusinessRuleBase Rule { get; internal set; }
57
61 public object Target { get; internal set; }
62
67 public Dictionary<Csla.Core.IPropertyInfo, object> InputPropertyValues { get; internal set; }
68
69 private LazySingleton<List<IPropertyInfo>> _dirtyProperties;
76 [EditorBrowsable(EditorBrowsableState.Never)]
77 public List<IPropertyInfo> DirtyProperties
78 {
79 get
80 {
81 if (!_dirtyProperties.IsValueCreated)
82 return null;
83 return _dirtyProperties.Value;
84 }
85 }
86
87 private readonly LazySingleton<Dictionary<IPropertyInfo, object>> _outputPropertyValues;
92 [EditorBrowsable(EditorBrowsableState.Never)]
93 public Dictionary<Csla.Core.IPropertyInfo, object> OutputPropertyValues
94 {
95 get
96 {
97 if (!_outputPropertyValues.IsValueCreated)
98 return null;
99 return _outputPropertyValues.Value;
100 }
101 }
102
107 private List<RuleResult> _results;
112 [EditorBrowsable(EditorBrowsableState.Never)]
113 public List<RuleResult> Results
114 {
115 get
116 {
117 if (_results == null)
118 _results = new List<RuleResult>();
119 return _results;
120 }
121 private set
122 {
123 _results = value;
124 }
125 }
126
127 private readonly Action<IRuleContext> _completeHandler;
128
133 [EditorBrowsable(EditorBrowsableState.Never)]
134 public string OriginPropertyName { get; internal set; }
135
140 public RuleContextModes ExecuteContext { get; internal set; }
141
142
148 public void ExecuteRule(IBusinessRuleBase innerRule)
149 {
150 var chainedContext = GetChainedContext(innerRule);
151 if (BusinessRules.CanRunRule(ApplicationContext, innerRule, chainedContext.ExecuteContext))
152 {
153 if (innerRule is IBusinessRule syncRule)
154 syncRule.Execute(chainedContext);
155 else if (innerRule is IBusinessRuleAsync asyncRule)
156 asyncRule.ExecuteAsync(chainedContext).ContinueWith((t) => { chainedContext.Complete(); });
157 else
158 throw new ArgumentOutOfRangeException(innerRule.GetType().FullName);
159 }
160 }
161
168 [EditorBrowsable(EditorBrowsableState.Never)]
170 {
171 get { return (ExecuteContext & RuleContextModes.AsAffectedPoperty) > 0; }
172 }
173
180 [EditorBrowsable(EditorBrowsableState.Never)]
182 {
183 get { return (ExecuteContext & RuleContextModes.PropertyChanged) > 0; }
184 }
185
192 [EditorBrowsable(EditorBrowsableState.Never)]
194 {
195 get { return (ExecuteContext & RuleContextModes.CheckRules) > 0; }
196 }
197
204 [EditorBrowsable(EditorBrowsableState.Never)]
206 {
207 get { return (ExecuteContext & RuleContextModes.CheckObjectRules) > 0; }
208 }
209
210 internal RuleContext(ApplicationContext applicationContext, Action<IRuleContext> completeHandler)
211 {
212 ApplicationContext = applicationContext ?? throw new ArgumentNullException(nameof(applicationContext));
213 _completeHandler = completeHandler;
214 _outputPropertyValues =
216 _dirtyProperties =
218 }
219
220 internal RuleContext(ApplicationContext applicationContext, Action<IRuleContext> completeHandler, RuleContextModes executeContext)
221 : this(applicationContext, completeHandler)
222 {
223 ExecuteContext = executeContext;
224 }
225
226 internal RuleContext(ApplicationContext applicationContext, Action<IRuleContext> completeHandler, LazySingleton<Dictionary<IPropertyInfo, object>> outputPropertyValues, LazySingleton<List<IPropertyInfo>> dirtyProperties, RuleContextModes executeContext)
227 {
228 ApplicationContext = applicationContext ?? throw new ArgumentNullException(nameof(applicationContext));
229 ExecuteContext = executeContext;
230 _completeHandler = completeHandler;
231 _outputPropertyValues = outputPropertyValues;
232 _dirtyProperties = dirtyProperties;
233 }
234
243 public RuleContext(ApplicationContext applicationContext, Action<IRuleContext> completeHandler, IBusinessRuleBase rule, object target, Dictionary<Csla.Core.IPropertyInfo, object> inputPropertyValues)
244 : this(applicationContext, completeHandler)
245 {
246 Rule = rule;
247 if (rule.PrimaryProperty != null)
249 Target = target;
250 InputPropertyValues = inputPropertyValues;
251 ExecuteContext = RuleContextModes.PropertyChanged;
252 }
253
266 {
267 var result = new RuleContext(ApplicationContext, _completeHandler, _outputPropertyValues, _dirtyProperties, ExecuteContext);
268 result.Rule = rule;
269 result.OriginPropertyName = OriginPropertyName;
270 result.InputPropertyValues = InputPropertyValues;
271 result.Results = Results;
272
273 if (!rule.IsAsync || rule.ProvideTargetWhenAsync)
274 result.Target = Target;
275 return result;
276 }
277
283 public void AddErrorResult(string description)
284 {
285 Results.Add(new RuleResult(Rule.RuleName, Rule.PrimaryProperty, description));
286 }
287
295 public void AddErrorResult(string description, bool stopProcessing)
296 {
297 Results.Add(new RuleResult(Rule.RuleName, Rule.PrimaryProperty, description) { StopProcessing = stopProcessing });
298 }
299
308 public void AddErrorResult(Csla.Core.IPropertyInfo property, string description)
309 {
310 if (!Rule.AffectedProperties.Contains(property))
311 throw new ArgumentOutOfRangeException(property.Name, string.Format(Resources.PropertyNotInAffectedPropertiesException, property.Name));
312 Results.Add(new RuleResult(Rule.RuleName, property, description));
313 }
314
320 public void AddWarningResult(string description)
321 {
322 Results.Add(new RuleResult(Rule.RuleName, Rule.PrimaryProperty, description) { Severity = RuleSeverity.Warning });
323 }
324
332 public void AddWarningResult(string description, bool stopProcessing)
333 {
334 Results.Add(new RuleResult(Rule.RuleName, Rule.PrimaryProperty, description) { Severity = RuleSeverity.Warning, StopProcessing = stopProcessing });
335 }
336
337
345 public void AddWarningResult(Csla.Core.IPropertyInfo property, string description)
346 {
347 if (!Rule.AffectedProperties.Contains(property))
348 throw new ArgumentOutOfRangeException(property.Name, string.Format(Resources.PropertyNotInAffectedPropertiesException, property.Name));
349 Results.Add(new RuleResult(Rule.RuleName, property, description) { Severity = RuleSeverity.Warning });
350 }
351
357 public void AddInformationResult(string description)
358 {
359 Results.Add(new RuleResult(Rule.RuleName, Rule.PrimaryProperty, description) { Severity = RuleSeverity.Information });
360 }
361
367 public void AddInformationResult(string description, bool stopProcessing)
368 {
369 Results.Add(new RuleResult(Rule.RuleName, Rule.PrimaryProperty, description) { Severity = RuleSeverity.Information, StopProcessing = stopProcessing });
370 }
371
379 public void AddInformationResult(Csla.Core.IPropertyInfo property, string description)
380 {
381 if (!Rule.AffectedProperties.Contains(property))
382 throw new ArgumentOutOfRangeException(property.Name, string.Format(Resources.PropertyNotInAffectedPropertiesException, property.Name));
383 Results.Add(new RuleResult(Rule.RuleName, property, description) { Severity = RuleSeverity.Information });
384 }
385
390 public void AddSuccessResult(bool stopProcessing)
391 {
392 Results.Add(new RuleResult(Rule.RuleName, Rule.PrimaryProperty) { Severity = RuleSeverity.Success, StopProcessing = stopProcessing });
393 }
394
400 public void AddOutValue(object value)
401 {
402 _outputPropertyValues.Value.Add(Rule.PrimaryProperty, value);
403 }
404
412 public void AddOutValue(Csla.Core.IPropertyInfo property, object value)
413 {
414 _outputPropertyValues.Value[property] = value;
415 }
416
417
423 [EditorBrowsable(EditorBrowsableState.Never)]
425 {
426 if (!Rule.AffectedProperties.Contains(property))
427 throw new ArgumentOutOfRangeException(property.Name, string.Format(Resources.PropertyNotInAffectedPropertiesException, property.Name));
428 _dirtyProperties.Value.Add(property);
429 }
430
436 public void Complete()
437 {
438 if (Results.Count == 0)
440 _completeHandler?.Invoke(this);
441 }
442
449 public T GetInputValue<T>(PropertyInfo<T> propertyInfo)
450 {
451 return (T)InputPropertyValues[propertyInfo];
452 }
453
460 public T GetInputValue<T>(IPropertyInfo propertyInfo)
461 {
462 return (T)InputPropertyValues[propertyInfo];
463 }
464
472 public bool TryGetInputValue<T>(PropertyInfo<T> propertyInfo, ref T value)
473 {
474 if (!InputPropertyValues.ContainsKey(propertyInfo))
475 {
476 value = default(T);
477 return false;
478 }
479
480 value = (T)InputPropertyValues[propertyInfo];
481 return true;
482 }
483
491 public bool TryGetInputValue<T>(IPropertyInfo propertyInfo, ref T value)
492 {
493 if (!InputPropertyValues.ContainsKey(propertyInfo))
494 {
495 value = default(T);
496 return false;
497 }
498
499 value = (T)InputPropertyValues[propertyInfo];
500 return true;
501 }
502
506 public ApplicationContext ApplicationContext { get; private set; }
507
512 (IDataPortalFactory)ApplicationContext.CurrentServiceProvider.GetService(typeof(IDataPortalFactory));
513 }
514}
Provides consistent context information between the client and server DataPortal objects.
object CreateInstanceDI(Type objectType, params object[] parameters)
Creates an object using 'Activator.CreateInstance' using service provider (if one is available) to po...
An alternative to Lazy<T>
T Value
Gets the instance.
bool IsValueCreated
Gets a value indicating whether this instance is initilized and contains a value.
A strongly-typed resource class, for looking up localized strings, etc.
static string PropertyNotInAffectedPropertiesException
Looks up a localized string similar to Property {0} must be added to AffectedProperties.
Maintains metadata about a property.
Tracks the business rules for a business object.
Context information provided to a business rule when it is invoked.
Definition: RuleContext.cs:51
void AddWarningResult(string description)
Add a Warning severity result to the Results list.
Definition: RuleContext.cs:320
void AddSuccessResult(bool stopProcessing)
Add a Success severity result to the Results list.
Definition: RuleContext.cs:390
object Target
Gets a reference to the target business object.
Definition: RuleContext.cs:61
Dictionary< Csla.Core.IPropertyInfo, object > OutputPropertyValues
Gets a dictionary containing copies of property values that should be updated in the target object.
Definition: RuleContext.cs:94
List< IPropertyInfo > DirtyProperties
Gets a list of dirty properties (value was updated).
Definition: RuleContext.cs:78
bool IsPropertyChangedContext
Gets a value indicating whether this instance is property changed context.
Definition: RuleContext.cs:182
bool IsCheckObjectRulesContext
Gets a value indicating whether this instance is check object rules context.
Definition: RuleContext.cs:206
void AddErrorResult(Csla.Core.IPropertyInfo property, string description)
Add a Error severity result to the Results list.
Definition: RuleContext.cs:308
List< RuleResult > Results
Gets a list of RuleResult objects containing the results of the rule.
Definition: RuleContext.cs:114
void AddWarningResult(string description, bool stopProcessing)
Add a Warning severity result to the Results list.
Definition: RuleContext.cs:332
RuleContextModes ExecuteContext
Gets the execution context.
Definition: RuleContext.cs:140
RuleContext(ApplicationContext applicationContext, Action< IRuleContext > completeHandler, IBusinessRuleBase rule, object target, Dictionary< Csla.Core.IPropertyInfo, object > inputPropertyValues)
Creates a RuleContext instance for unit tests.
Definition: RuleContext.cs:243
void AddErrorResult(string description)
Add a Error severity result to the Results list.
Definition: RuleContext.cs:283
void AddWarningResult(Csla.Core.IPropertyInfo property, string description)
Add a Warning severity result to the Results list.
Definition: RuleContext.cs:345
void AddErrorResult(string description, bool stopProcessing)
Add a Error severity result to the Results list.
Definition: RuleContext.cs:295
bool TryGetInputValue< T >(PropertyInfo< T > propertyInfo, ref T value)
Tries to get the value.
Definition: RuleContext.cs:472
void ExecuteRule(IBusinessRuleBase innerRule)
Executes the inner rule from the outer rules context.
Definition: RuleContext.cs:148
void AddOutValue(Csla.Core.IPropertyInfo property, object value)
Add an outbound value to update a property on the business object once the rule is complete.
Definition: RuleContext.cs:412
void Complete()
Indicates that the rule processing is complete, so CSLA .NET will process the Results list.
Definition: RuleContext.cs:436
void AddDirtyProperty(Csla.Core.IPropertyInfo property)
Adds a property name as a dirty field (changed value).
Definition: RuleContext.cs:424
void AddInformationResult(string description, bool stopProcessing)
Add an Information severity result to the Results list.
Definition: RuleContext.cs:367
void AddInformationResult(string description)
Add an Information severity result to the Results list.
Definition: RuleContext.cs:357
Dictionary< Csla.Core.IPropertyInfo, object > InputPropertyValues
Gets a dictionary containing copies of property values from the target business object.
Definition: RuleContext.cs:67
IRuleContext GetChainedContext(IBusinessRuleBase rule)
Gets a new RuleContext object for a chained rule.
Definition: RuleContext.cs:265
string OriginPropertyName
Gets or sets the name of the origin property.
Definition: RuleContext.cs:134
bool IsCascadeContext
Gets a value indicating whether this instance is cascade context as a result of AffectedProperties.
Definition: RuleContext.cs:170
void AddOutValue(object value)
Add an outbound value to update the rule's primary property on the business object once the rule is c...
Definition: RuleContext.cs:400
IBusinessRuleBase Rule
Gets the rule object.
Definition: RuleContext.cs:56
IDataPortalFactory DataPortalFactory
Gets a data portal factory instance
Definition: RuleContext.cs:511
bool IsCheckRulesContext
Gets a value indicating whether this instance is check rules context.
Definition: RuleContext.cs:194
void AddInformationResult(Csla.Core.IPropertyInfo property, string description)
Add an Information severity result to the Results list.
Definition: RuleContext.cs:379
ApplicationContext ApplicationContext
Gets a reference to the current ApplicationContext.
Definition: RuleContext.cs:506
T GetInputValue< T >(PropertyInfo< T > propertyInfo)
Gets the value.
Definition: RuleContext.cs:449
Contains information about the result of a rule.
Definition: RuleResult.cs:20
string Name
Gets the member name value.
Definition: IMemberInfo.cs:23
Maintains metadata about a property.
Defines a data portal service used to get an access to a client-side data portal instance.
Interface defining a business/validation rule implementation.
Interface defining a business/validation rule implementation.
bool IsAsync
Gets a value indicating whether the Execute() method will run asynchronous code.
bool ProvideTargetWhenAsync
Gets a value indicating that the Target property should be set even for an async rule (note that usin...
List< Csla.Core.IPropertyInfo > AffectedProperties
Gets a list of properties affected by this rule.
Csla.Core.IPropertyInfo PrimaryProperty
Gets the primary property affected by this rule.
string RuleName
Gets a unique rule:// URI for the specific instance of the rule within the context of the business ob...
Interface defining a business/validation rule implementation.
Context information provided to a business rule when it is invoked.
Definition: IRuleContext.cs:22
RuleContextModes
RuleContext mode flags
Definition: RuleContext.cs:23
@ PropertyChanged
Called from PropertyHasChanged event on BO but not including cascade calls by AffectedProperties
@ CheckObjectRules
Called from CheckObjectRules
@ AsAffectedPoperty
Include cascaded calls by AffectedProperties
@ CheckRules
Called from CheckRules
@ Any
Default value, rule can run in any context