예제 #1
0
        private void CheckForCyclesInternal(
            ref Subgraph used,
            BindingExtenderBox box,
            IBindingContainer bindingContainer
            )
        {
            if (used is null)
            {
                throw new ArgumentNullException(nameof(used));
            }

            if (box is null)
            {
                throw new ArgumentNullException(nameof(box));
            }

            if (bindingContainer is null)
            {
                throw new ArgumentNullException(nameof(bindingContainer));
            }

            used.AppendOrFailIfExists(
                bindingContainer,
                !bindingContainer.IsConditional
                );

            if (box.TryGetChildren(bindingContainer, true, out var pairs))
            {
                foreach (var pair in pairs)
                {
                    var used2 = used.Clone();

                    CheckForCyclesInternal(
                        ref used2,
                        box,
                        pair.BindingExtender.BindingContainer
                        );
                }
            }
        }
예제 #2
0
 private Subgraph(Subgraph subgraph)
 {
     _used       = new HashSet <IBindingContainer>(subgraph._used, subgraph._used.Comparer);
     _usedInList = new List <IBindingContainer>(subgraph._usedInList);
     _idempotent = subgraph._idempotent;
 }
예제 #3
0
        public void CheckForCycles(
            BindingExtenderBox box
            )
        {
            if (box is null)
            {
                throw new ArgumentNullException(nameof(box));
            }

            var cycles = new HashSet <CycleFoundException>(
                new OrderIndependentCycleFoundEqualityComparer()
                );

            foreach (var pair in box.Groups.Shuffle())
            {
                var group = pair.Value;
                foreach (var bindingExtender in group.BindingExtenders.Shuffle())
                {
                    var doCircularCheck = true;
                    if (bindingExtender.BindingContainer.Settings.TryGetSettingInScope <CircularSetting>(CircularSetting.ScopeConstant, out var setting))
                    {
                        doCircularCheck = setting.DoCircularCheck;
                    }

                    if (!doCircularCheck)
                    {
                        continue;
                    }

                    try
                    {
                        var used = new Subgraph();

                        CheckForCyclesInternal(
                            ref used,
                            box,
                            bindingExtender.BindingContainer
                            );
                    }
                    catch (CycleFoundException cfe)
                    {
                        if (!cycles.Contains(cfe))
                        {
                            cycles.Add(cfe);
                        }
                    }
                }
            }

            foreach (var cycle in cycles)
            {
                if (cycle.StrictConculsion)
                {
                    throw new DpdtException(
                              DpdtExceptionTypeEnum.CircularDependency,
                              $"A circular dependency was found: [{cycle.GetStringRepresentation()}]"
                              );
                }
                else
                {
                    _reporter.ReportWarning(
                        $"Perhaps a circular dependency was found",
                        $"Perhaps a circular dependency was found, please take a look: [{cycle.GetStringRepresentation()}]"
                        );
                }
            }
        }