Exemplo n.º 1
0
        /// <inheritdoc/>
        public virtual void DeriveWantFacts <TWantAction, TFactContainer>(WantActionInfo <TWantAction, TFactContainer> wantActionInfo)
            where TWantAction : IWantAction
            where TFactContainer : IFactContainer
        {
            (var context, var wantAction, var buildSuccessConditions, var runtimeConditions) =
                (wantActionInfo.Context, wantActionInfo.Context.WantAction, wantActionInfo.BuildSuccessConditions, wantActionInfo.RuntimeConditions);

            foreach (var condition in runtimeConditions)
            {
                if (!RuntimeCondition(condition, context))
                {
                    throw CommonHelper.CreateDeriveException(
                              ErrorCode.RuntimeCondition,
                              $"Failed to meet {context.Cache.GetFactType(condition).FactName} for {wantAction} and find another solution.");
                }
            }

            using (var writer = context.Container.GetWriter())
            {
                buildSuccessConditions.ForEach(writer.Add);
                runtimeConditions.ForEach(writer.Add);
            }

            var requiredFacts = GetRequireFacts(context.WantAction, context);

            if (!CanInvokeWork(requiredFacts, context.WantAction, context.Cache))
            {
                throw CommonHelper.CreateDeriveException(ErrorCode.InvalidOperation, $"Can't invoke the '{context.WantAction}' action.", context.WantAction, context.Container);
            }

            context.WantAction.Invoke(requiredFacts);

            using (var writer = context.Container.GetWriter())
            {
                buildSuccessConditions.ForEach(writer.Remove);
                runtimeConditions.ForEach(writer.Remove);
            }
        }
        /// <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);
                }
        /// <inheritdoc/>
        public override async ValueTask DeriveWantFactsAsync <TWantAction, TFactContainer>(WantActionInfo <TWantAction, TFactContainer> wantActionInfo)
        {
            await base.DeriveWantFactsAsync(wantActionInfo).ConfigureAwait(false);

            WriteLog(() => $"FactFactory | WantAction\n{wantActionInfo.Context.WantAction}\nInput facts: {string.Join(", ", GetRequireFacts(wantActionInfo.Context.WantAction, wantActionInfo.Context))}");
        }
 /// <inheritdoc/>
 public override void DeriveWantFacts <TWantAction, TFactContainer>(WantActionInfo <TWantAction, TFactContainer> wantActionInfo)
 {
     base.DeriveWantFacts(wantActionInfo);
     WriteLog(() => $"FactFactory | WantAction\n{wantActionInfo.Context.WantAction}\nInput facts: {string.Join(", ", GetRequireFacts(wantActionInfo.Context.WantAction, wantActionInfo.Context))}");
 }