예제 #1
0
        public static IEnumerable <DependencyCycle <T> > VisitCycles <T>(this IEnumerable <DependencyCycle <T> > cycles,
                                                                         VisitCycleHandler <T> visit)
        {
            var mc = new Dictionary <DependencyCycle <T>, DependencyCycle <T> >();


            var setComparer = HashSetEqualityComparer <DependencyCycle <T> > .Default;

            return(VisitCyclesCore(cycles, () => { }, mc, visit, setComparer));
        }
예제 #2
0
        private static IEnumerable <DependencyCycle <T> > VisitCyclesCore <T>(IEnumerable <DependencyCycle <T> > cycles,
                                                                              Action cancelled,
                                                                              IDictionary <DependencyCycle <T>, DependencyCycle <T> > cache,
                                                                              VisitCycleHandler <T> visit,
                                                                              IEqualityComparer <HashSet <DependencyCycle <T> > > setComparer)
        {
            foreach (var cycle in cycles)
            {
                if (cache.TryGetValue(cycle, out var newCycle))
                {
                    yield return(cycle);

                    continue;
                }

                var dependenciesChanged = false;

                var dependencies = cycle.Dependencies as HashSet <DependencyCycle <T> > ?? cycle.Dependencies.ToHashSet();

                if (dependencies.Count > 0)
                {
                    var wasCancelled    = false;
                    var dependenciesSet = VisitCyclesCore(dependencies, () => wasCancelled = true, cache, visit, setComparer)
                                          .ToHashSet();

                    if (wasCancelled)
                    {
                        cancelled();
                        yield break;
                    }

                    if (!setComparer.Equals(dependenciesSet, dependencies))
                    {
                        dependenciesChanged = true;
                        dependencies        = dependenciesSet;
                    }
                }

                newCycle = visit(cycle, dependenciesChanged, dependencies);
                if (newCycle == null)
                {
                    cancelled();
                    yield break;
                }

                if (newCycle == cycle && dependenciesChanged)
                {
                    newCycle = new DependencyCycle <T>(cycle.Contents, dependencies);
                }

                cache.Add(cycle, newCycle);
                yield return(newCycle);
            }
        }