/// <inheritdoc/> public virtual async ValueTask <IFact> CalculateFactAsync <TFactRule, TWantAction, TFactContainer>(NodeByFactRule <TFactRule> node, IWantActionContext <TWantAction, TFactContainer> context) where TFactRule : IFactRule where TWantAction : IWantAction where TFactContainer : IFactContainer { (var rule, var buildSuccessConditions, var runtimeConditions) = (node.Info.Rule, node.Info.BuildSuccessConditions, node.Info.RuntimeConditions); foreach (IRuntimeConditionFact condition in runtimeConditions) { (bool calculated, IFact result) = await TryCalculateFactByRuntimeConditionAsync(rule, condition, context); if (calculated) { return(result); } } using (var writer = context.Container.GetWriter()) { buildSuccessConditions.ForEach(writer.Add); runtimeConditions.ForEach(writer.Add); } var requiredFacts = GetRequireFacts(rule, context); if (!CanInvokeWork(requiredFacts, rule, context.Cache)) { throw CommonHelper.CreateDeriveException(ErrorCode.InvalidOperation, $"Can't calculate the '{rule}' rule.", context.WantAction, context.Container); } IFact fact = await Factory .CreateObject(facts => rule.CalculateAsync(facts), requiredFacts) .ConfigureAwait(false); fact.SetCalculateByRule(); context.WantAction.AddUsedRule(rule); using (var writer = context.Container.GetWriter()) { buildSuccessConditions.ForEach(writer.Remove); runtimeConditions.ForEach(writer.Remove); } return(fact); }