Skip to content

Commit

Permalink
MarimerLLC#409 Allow async Task business rules via IBusinessRuleAsync…
Browse files Browse the repository at this point in the history
… and BusinessRuleAsync
  • Loading branch information
rockfordlhotka committed May 25, 2019
1 parent c80cf09 commit e5c3bb9
Show file tree
Hide file tree
Showing 12 changed files with 387 additions and 271 deletions.
2 changes: 2 additions & 0 deletions Source/Csla.Shared/Csla.Shared.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@
<Compile Include="$(MSBuildThisFileDirectory)Rules\BrokenRulesTree.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Rules\BrukenRulesNode.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Rules\BusinessRule.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Rules\BusinessRuleAsync.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Rules\BusinessRuleBase.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Rules\BusinessRuleManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Rules\BusinessRules.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Rules\BusinessRulesExtensions.cs" />
Expand Down
184 changes: 5 additions & 179 deletions Source/Csla.Shared/Rules/BusinessRule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,21 @@
// </copyright>
// <summary>Base class used to create business and validation</summary>
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Csla.Properties;

namespace Csla.Rules
{


/// <summary>
/// Base class used to create business and validation
/// rules.
/// </summary>
public abstract class BusinessRule : IBusinessRule
public abstract class BusinessRule : BusinessRuleBase, IBusinessRule
{
private Csla.Core.IPropertyInfo _primaryProperty;

private bool _isAsync;
private RunModes _runMode;
private bool _provideTargetWhenAsync;
private int _priority;
private RuleUri _ruleUri;
private bool _locked;

/// <summary>
/// Gets or sets the primary property affected by this rule.
/// </summary>
public virtual Csla.Core.IPropertyInfo PrimaryProperty
{
get { return _primaryProperty; }
set
{
CanWriteProperty("PrimaryProperty");
_primaryProperty = value;
this.RuleUri = new RuleUri(this, value);
if (_primaryProperty != null)
AffectedProperties.Add(_primaryProperty);
}
}
/// <summary>
/// Gets a list of properties affected by this rule. Rules for these
/// properties are executed after rules for the primary
/// property.
/// </summary>
public List<Csla.Core.IPropertyInfo> AffectedProperties { get; private set; }
/// <summary>
/// Gets a list of secondary property values to be supplied to the
/// rule when it is executed.
/// </summary>
public List<Csla.Core.IPropertyInfo> InputProperties { get; protected set; }


/// <summary>
/// Gets a value indicating whether the rule will run
/// on a background thread.
/// </summary>
public bool IsAsync
public override bool IsAsync
{
get { return _isAsync; }
protected set
Expand All @@ -72,79 +29,6 @@ protected set
}
}


/// <summary>
/// Gets a value indicating that the Target property should
/// be set even for an async rule (note that using Target
/// from a background thread will cause major problems).
/// </summary>
public bool ProvideTargetWhenAsync
{
get { return _provideTargetWhenAsync; }
protected set
{
CanWriteProperty("ProvideTargetWhenAsync");
_provideTargetWhenAsync = value;
}
}

/// <summary>
/// Gets a unique rule:// URI for the specific instance
/// of the rule within the context of the business object
/// where the rule is used.
/// </summary>
public string RuleName { get { return this.RuleUri.ToString(); } }


/// <summary>
/// Sets or gets the rule:// URI object for this rule.
/// </summary>
protected RuleUri RuleUri
{
get { return _ruleUri; }
set
{
CanWriteProperty("RuleUri");
_ruleUri = value;
}
}


/// <summary>
/// Gets the rule priority.
/// </summary>
public int Priority
{
get { return _priority; }
set
{
CanWriteProperty("Priority");
_priority = value;
}
}



/// <summary>
/// Gets or sets the run in context.
/// </summary>
/// <value>The run in context.</value>
public RunModes RunMode
{
get { return _runMode; }
set
{
CanWriteProperty("RunMode");
_runMode = value;
}
}

private void CanWriteProperty(string argument)
{
if (_locked) throw
new ArgumentException(string.Format("{0} ({1})", Resources.PropertySetNotAllowed, argument), argument);
}

/// <summary>
/// Creates an instance of the rule that applies
/// to a business object as a whole.
Expand All @@ -159,13 +43,8 @@ protected BusinessRule()
/// </summary>
/// <param name="primaryProperty">Primary property for this rule.</param>
protected BusinessRule(Csla.Core.IPropertyInfo primaryProperty)
{
AffectedProperties = new List<Core.IPropertyInfo>();
InputProperties = new List<Core.IPropertyInfo>();
PrimaryProperty = primaryProperty;
this.RuleUri = new RuleUri(this, primaryProperty);
RunMode = RunModes.Default;
}
: base(primaryProperty)
{ }

/// <summary>
/// Business or validation rule implementation.
Expand All @@ -176,61 +55,8 @@ protected virtual void Execute(IRuleContext context)

void IBusinessRule.Execute(IRuleContext context)
{
if (!_locked)
_locked = true;
PropertiesLocked = true;
Execute(context);
}

#region Load/Read Property

/// <summary>
/// Loads a property's managed field with the
/// supplied value calling PropertyHasChanged
/// if the value does change.
/// </summary>
/// <param name="obj">
/// Object on which to call the method.
/// </param>
/// <param name="propertyInfo">
/// PropertyInfo object containing property metadata.</param>
/// <param name="newValue">
/// The new value for the property.</param>
/// <remarks>
/// No authorization checks occur when this method is called,
/// and no PropertyChanging or PropertyChanged events are raised.
/// Loading values does not cause validation rules to be
/// invoked.
/// </remarks>
protected void LoadProperty(object obj, Csla.Core.IPropertyInfo propertyInfo, object newValue)
{
var target = obj as Core.IManageProperties;
if (target != null)
target.LoadProperty(propertyInfo, newValue);
else
throw new ArgumentException(Resources.IManagePropertiesRequiredException);
}

/// <summary>
/// Reads a property's field value.
/// </summary>
/// <param name="obj">
/// Object on which to call the method.
/// </param>
/// <param name="propertyInfo">
/// PropertyInfo object containing property metadata.</param>
/// <remarks>
/// No authorization checks occur when this method is called.
/// </remarks>
protected object ReadProperty(object obj, Csla.Core.IPropertyInfo propertyInfo)
{
var target = obj as Core.IManageProperties;
if (target != null)
return target.ReadProperty(propertyInfo);
else
throw new ArgumentException(Resources.IManagePropertiesRequiredException);
}

#endregion

}
}
67 changes: 67 additions & 0 deletions Source/Csla.Shared/Rules/BusinessRuleAsync.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#if !NET40 && !NET45
//-----------------------------------------------------------------------
// <copyright file="BusinessRuleAsync.cs" company="Marimer LLC">
// Copyright (c) Marimer LLC. All rights reserved.
// Website: https://cslanet.com
// </copyright>
// <summary>Base class used to create business and validation</summary>
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Csla.Properties;

namespace Csla.Rules
{
/// <summary>
/// Base class used to create async
/// business and validation rules.
/// </summary>
public abstract class BusinessRuleAsync : BusinessRuleBase, IBusinessRuleAsync
{
/// <summary>
/// Gets a value indicating whether the rule will run
/// on a background thread.
/// </summary>
public override bool IsAsync
{
get { return true; }
protected set { }
}

/// <summary>
/// Creates an instance of the rule that applies
/// to a business object as a whole.
/// </summary>
protected BusinessRuleAsync()
: this(null)
{ }

/// <summary>
/// Creates an instance of the rule that applies
/// to a specfic property.
/// </summary>
/// <param name="primaryProperty">Primary property for this rule.</param>
protected BusinessRuleAsync(Csla.Core.IPropertyInfo primaryProperty)
: base(primaryProperty)
{ }

/// <summary>
/// Business or validation rule implementation.
/// </summary>
/// <param name="context">Rule context object.</param>
protected virtual Task ExecuteAsync(IRuleContext context)
{
return Task.CompletedTask;
}

Task IBusinessRuleAsync.ExecuteAsync(IRuleContext context)
{
PropertiesLocked = true;
return ExecuteAsync(context);
}
}
}
#endif
Loading

0 comments on commit e5c3bb9

Please sign in to comment.