public IEnumerable <ContributorCall> GenerateCallGraph(IEnumerable <IPipelineContributor> contributors) { contributors = contributors.ToList(); var bootstrapper = contributors .OfType <KnownStages.IBegin>() .SingleOrDefault() ?? throw new InvalidOperationException("No IBegin contributor found."); var nodes = new List <TopologicalNode <ContributorNotification> >(); foreach (var contributor in contributors.Where(x => x != bootstrapper)) { var contributorBuilder = new ContributorInitializer(contributors); var builder = new CompatibilityContributorInitializer(contributorBuilder); contributor.Initialize(builder); nodes.AddRange( contributorBuilder.ContributorRegistrations .DefaultIfEmpty(new Notification( Middleware.IdentitySingleTap, contributorBuilder.Contributors)) .Select(reg => new TopologicalNode <ContributorNotification>( new ContributorNotification(contributor, reg)))); } foreach (var notificationNode in nodes) { foreach (var afterType in notificationNode.Item.Notification.AfterTypes) { var parents = GetCompatibleNodes(nodes, notificationNode, afterType); notificationNode.Dependencies.AddRange(parents); } foreach (var beforeType in notificationNode.Item.Notification.BeforeTypes) { var children = GetCompatibleNodes(nodes, notificationNode, beforeType); foreach (var child in children) { child.Dependencies.Add(notificationNode); } } } var rootItem = new ContributorNotification(bootstrapper, new Notification(Middleware.IdentitySingleTap, contributors)); return(new TopologicalTree <ContributorNotification>(rootItem, nodes).Nodes .Select( n => new ContributorCall(n.Item.Contributor, n.Item.Notification.Target, n.Item.Notification.Description))); }
public IEnumerable <ContributorCall> GenerateCallGraph(IEnumerable <IPipelineContributor> contributors) { contributors = contributors.ToList(); var bootstrapper = contributors.OfType <KnownStages.IBegin>().Single(); var tree = new DependencyTree <ContributorNotification>( new ContributorNotification(bootstrapper, new Notification(Middleware.IdentitySingleTap, contributors))); foreach (var contrib in contributors.Where(x => x != bootstrapper)) { var contributorBuilder = new ContributorInitializer(contributors); var builder = new CompatibilityContributorInitializer(contributorBuilder); contrib.Initialize(builder); var contributorRegistrations = contributorBuilder.ContributorRegistrations.DefaultIfEmpty(new Notification(Middleware.IdentitySingleTap, contributors)).ToList(); foreach (var registration in contributorRegistrations) { tree.CreateNode(new ContributorNotification(contrib, registration)); } } foreach (var notificationNode in tree.Nodes) { foreach (var parentNode in GetCompatibleTypes(tree, notificationNode, notificationNode.Value.Notification.AfterTypes)) { parentNode.ChildNodes.Add(notificationNode); } foreach (var childNode in GetCompatibleTypes(tree, notificationNode, notificationNode.Value.Notification.BeforeTypes)) { childNode.ParentNodes.Add(notificationNode); } } return (tree.GetCallGraph() .Select( x => new ContributorCall(x.Value.Contributor, x.Value.Notification.Target, x.Value.Notification.Description))); }