/// <inheritdoc/> public virtual void DeriveWantAction <TFactRule, TFactRuleCollection, TWantAction, TFactContainer>(List <DeriveWantActionRequest <TFactRule, TFactRuleCollection, TWantAction, TFactContainer> > requests) where TFactRule : IFactRule where TFactRuleCollection : IFactRuleCollection <TFactRule> where TWantAction : IWantAction where TFactContainer : IFactContainer { Validate(requests); var treesByActions = new Dictionary <WantActionInfo <TWantAction, TFactContainer>, List <TreeByFactRule <TFactRule, TWantAction, TFactContainer> > >(); var deriveErrorDetails = new List <DeriveErrorDetail>(); foreach (DeriveWantActionRequest <TFactRule, TFactRuleCollection, TWantAction, TFactContainer> request in requests) { var context = request.Context; if (!context.WantAction.Option.HasFlag(FactWorkOption.CanExecuteSync)) { deriveErrorDetails.Add(new DeriveErrorDetail( ErrorCode.InvalidOperation, ErrorResources.OnWantActionCannotBePerformedSynchronously(context.WantAction), context.WantAction, context.Container, null)); continue; } var requestForAction = new BuildTreesForWantActionRequest <TFactRule, TWantAction, TFactContainer> { Context = context, FactRules = request .Rules .FindAll(factRule => factRule.Option.HasFlag(FactWorkOption.CanExecuteSync)) .SortByDescending(r => r, context.SingleEntity.GetRuleComparer <TFactRule, TWantAction, TFactContainer>(context)), }; if (context.TreeBuilding.TryBuildTreesForWantAction(requestForAction, out var resultForAction)) { treesByActions.Add(resultForAction.WantActionInfo, resultForAction.TreesResult); } else { deriveErrorDetails.Add(resultForAction.DeriveErrorDetail); } } // Check that we were able to adequately build the tree. if (deriveErrorDetails.Count != 0) { throw CommonHelper.CreateDeriveException(deriveErrorDetails); } foreach (var item in treesByActions) { item.Key.Context.TreeBuilding.CalculateTreeAndDeriveWantFacts(item.Key, item.Value); } }
/// <inheritdoc/> public virtual async ValueTask DeriveWantActionAsync <TFactRule, TFactRuleCollection, TWantAction, TFactContainer>(List <DeriveWantActionRequest <TFactRule, TFactRuleCollection, TWantAction, TFactContainer> > requests) where TFactRule : IFactRule where TFactRuleCollection : IFactRuleCollection <TFactRule> where TWantAction : IWantAction where TFactContainer : IFactContainer { Validate(requests); var treesByActions = new Dictionary <WantActionInfo <TWantAction, TFactContainer>, List <TreeByFactRule <TFactRule, TWantAction, TFactContainer> > >(); var deriveErrorDetails = new List <DeriveErrorDetail>(); foreach (DeriveWantActionRequest <TFactRule, TFactRuleCollection, TWantAction, TFactContainer> request in requests) { var context = request.Context; var requestForAction = new BuildTreesForWantActionRequest <TFactRule, TWantAction, TFactContainer> { Context = context, FactRules = request .Rules .SortByDescending(r => r, context.SingleEntity.GetRuleComparer <TFactRule, TWantAction, TFactContainer>(context)), }; if (context.TreeBuilding.TryBuildTreesForWantAction(requestForAction, out var resultForAction)) { treesByActions.Add(resultForAction.WantActionInfo, resultForAction.TreesResult); } else { deriveErrorDetails.Add(resultForAction.DeriveErrorDetail); } } // Check that we were able to adequately build the tree. if (deriveErrorDetails.Count != 0) { throw CommonHelper.CreateDeriveException(deriveErrorDetails); } foreach (var item in treesByActions) { await item.Key.Context.TreeBuilding.CalculateTreeAndDeriveWantFactsAsync(item.Key, item.Value); } }
/// <inheritdoc/> public bool TryBuildTreesForWantAction <TFactRule, TWantAction, TFactContainer>(BuildTreesForWantActionRequest <TFactRule, TWantAction, TFactContainer> request, out BuildTreesForWantActionResult <TFactRule, TWantAction, TFactContainer> result) where TFactRule : IFactRule where TWantAction : IWantAction where TFactContainer : IFactContainer { var context = request.Context; var deriveFactErrorDetails = new List <DeriveFactErrorDetail>(); var wantActionInfo = new WantActionInfo <TWantAction, TFactContainer> { BuildFailedConditions = new List <IBuildConditionFact>(), BuildSuccessConditions = new List <IBuildConditionFact>(), RuntimeConditions = new List <IRuntimeConditionFact>(), Context = context, }; result = new BuildTreesForWantActionResult <TFactRule, TWantAction, TFactContainer> { TreesResult = new List <TreeByFactRule <TFactRule, TWantAction, TFactContainer> >(), WantActionInfo = wantActionInfo, }; foreach (var needFactType in context.SingleEntity.GetRequiredTypesOfFacts(context.WantAction, context)) { if (needFactType.IsFactType <IBuildConditionFact>()) { if (wantActionInfo.BuildSuccessConditions.Exists(fact => context.Cache.GetFactType(fact).EqualsFactType(needFactType)) || wantActionInfo.BuildFailedConditions.Exists(fact => context.Cache.GetFactType(fact).EqualsFactType(needFactType))) { continue; } var condition = Factory.CreateObject( type => type.CreateBuildConditionFact <IBuildConditionFact>(), needFactType ); if (condition.Condition(context.WantAction, context, ct => ct.WantAction.GetCompatibleRulesEx(request.FactRules, context))) { result.WantActionInfo.BuildSuccessConditions.Add(condition); } else { result.WantActionInfo.BuildFailedConditions.Add(condition); deriveFactErrorDetails.Add(new DeriveFactErrorDetail(needFactType, null)); } continue; } if (needFactType.IsFactType <IRuntimeConditionFact>()) { var condition = Factory.CreateObject( type => type.CreateRuntimeConditionFact <IRuntimeConditionFact>(), needFactType); result.WantActionInfo.RuntimeConditions.Add(condition); continue; } var requestFactType = new BuildTreeForFactInfoRequest <TFactRule, TWantAction, TFactContainer> { WantFactType = needFactType, Context = new FactRulesContext <TFactRule, TWantAction, TFactContainer> { Cache = context.Cache, Container = context.Container, FactRules = context .WantAction .GetCompatibleRulesEx(request.FactRules, context), SingleEntity = context.SingleEntity, TreeBuilding = context.TreeBuilding, WantAction = context.WantAction, Engine = context.Engine, }, }; if (context.TreeBuilding.TryBuildTreeForFactInfo(requestFactType, out var resultTree, out var errorList)) { result.TreesResult.Add(resultTree); }