diff --git a/src/modules/Elsa.Workflows.Management/Contracts/IChildWorkflowFinder.cs b/src/modules/Elsa.Workflows.Management/Contracts/IChildWorkflowFinder.cs
new file mode 100644
index 000000000..351493fc5
--- /dev/null
+++ b/src/modules/Elsa.Workflows.Management/Contracts/IChildWorkflowFinder.cs
@@ -0,0 +1,17 @@
+using Elsa.Workflows.Models;
+
+namespace Elsa.Workflows.Management.Contracts;
+
+///
+/// Finds child workflows for a given workflow graph.
+///
+public interface IChildWorkflowFinder
+{
+ ///
+ /// Finds child workflows for a given workflow graph.
+ ///
+ /// The workflow graph.
+ /// The cancellation token.
+ /// A collection of child workflows.
+ Task> FindChildWorkflowsAsync(WorkflowGraph workflowGraph, CancellationToken cancellationToken = default);
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Management/Contracts/IWorkflowGraphNetworkBuilder.cs b/src/modules/Elsa.Workflows.Management/Contracts/IWorkflowGraphNetworkBuilder.cs
new file mode 100644
index 000000000..a22fd8aac
--- /dev/null
+++ b/src/modules/Elsa.Workflows.Management/Contracts/IWorkflowGraphNetworkBuilder.cs
@@ -0,0 +1,16 @@
+using Elsa.Workflows.Management.Models;
+
+namespace Elsa.Workflows.Management.Contracts;
+
+///
+/// Defines a visitor that can traverse and process workflow definitions.
+///
+public interface IWorkflowGraphNetworkBuilder
+{
+ ///
+ /// Builds a network of workflow graphs and their consumers.
+ ///
+ /// The cancellation token.
+ /// A network of workflow graphs and their consumers.
+ Task BuildAsync(CancellationToken cancellationToken = default);
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs b/src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs
index 3fdc5adf8..75b36b111 100644
--- a/src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs
+++ b/src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs
@@ -221,6 +221,7 @@ public class WorkflowManagementFeature : FeatureBase
.AddScoped()
.AddScoped()
.AddScoped()
+ .AddScoped()
.AddScoped()
.AddSingleton()
.AddSingleton()
@@ -233,6 +234,7 @@ public class WorkflowManagementFeature : FeatureBase
Services
.AddNotificationHandler()
.AddNotificationHandler()
+ .AddNotificationHandler()
;
Services.Configure(options =>
diff --git a/src/modules/Elsa.Workflows.Management/Handlers/UpdateConsumingWorkflows.cs b/src/modules/Elsa.Workflows.Management/Handlers/UpdateConsumingWorkflows.cs
new file mode 100644
index 000000000..c031fe183
--- /dev/null
+++ b/src/modules/Elsa.Workflows.Management/Handlers/UpdateConsumingWorkflows.cs
@@ -0,0 +1,13 @@
+using Elsa.Mediator.Contracts;
+using Elsa.Workflows.Management.Contracts;
+using Elsa.Workflows.Management.Notifications;
+
+namespace Elsa.Workflows.Management.Handlers;
+
+public class UpdateConsumingWorkflows(IWorkflowGraphNetworkBuilder workflowGraphNetworkBuilder) : INotificationHandler
+{
+ public async Task HandleAsync(WorkflowDefinitionPublished notification, CancellationToken cancellationToken)
+ {
+ var network = await workflowGraphNetworkBuilder.BuildAsync(cancellationToken);
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Management/Models/WorkflowGraphNetwork.cs b/src/modules/Elsa.Workflows.Management/Models/WorkflowGraphNetwork.cs
new file mode 100644
index 000000000..bb6ddc551
--- /dev/null
+++ b/src/modules/Elsa.Workflows.Management/Models/WorkflowGraphNetwork.cs
@@ -0,0 +1,3 @@
+namespace Elsa.Workflows.Management.Models;
+
+public record WorkflowGraphNetwork(HashSet Nodes);
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Management/Models/WorkflowGraphNode.cs b/src/modules/Elsa.Workflows.Management/Models/WorkflowGraphNode.cs
new file mode 100644
index 000000000..765f1c92b
--- /dev/null
+++ b/src/modules/Elsa.Workflows.Management/Models/WorkflowGraphNode.cs
@@ -0,0 +1,24 @@
+using Elsa.Workflows.Models;
+
+namespace Elsa.Workflows.Management.Models;
+
+///
+/// Represents an activity in the context of an hierarchical tree structure, providing access to its siblings, parents and children.
+///
+public class WorkflowGraphNode(WorkflowGraph workflowGraph)
+{
+ ///
+ /// Gets the workflow graph associated with this node.
+ ///
+ public WorkflowGraph WorkflowGraph { get; } = workflowGraph;
+
+ ///
+ /// Gets the parents of this node.
+ ///
+ public HashSet Predecessors { get; set; } = new();
+
+ ///
+ /// Gets the children of this node.
+ ///
+ public HashSet Successors { get; set; } = new();
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Management/Services/WorkflowGraphNetworkBuilder.cs b/src/modules/Elsa.Workflows.Management/Services/WorkflowGraphNetworkBuilder.cs
new file mode 100644
index 000000000..c725fbe3e
--- /dev/null
+++ b/src/modules/Elsa.Workflows.Management/Services/WorkflowGraphNetworkBuilder.cs
@@ -0,0 +1,99 @@
+using Elsa.Common.Models;
+using Elsa.Workflows.Management.Activities.WorkflowDefinitionActivity;
+using Elsa.Workflows.Management.Contracts;
+using Elsa.Workflows.Management.Filters;
+using Elsa.Workflows.Management.Models;
+using Elsa.Workflows.Models;
+
+namespace Elsa.Workflows.Management.Services;
+
+///
+public class WorkflowGraphNetworkBuilder(IWorkflowDefinitionStore workflowDefinitionStore, IWorkflowDefinitionService workflowDefinitionService) : IWorkflowGraphNetworkBuilder
+{
+ ///
+ public async Task BuildAsync(CancellationToken cancellationToken = default)
+ {
+ var workflowGraphs = (await GetAllWorkflowGraphsAsync(cancellationToken)).ToList();
+ var nodes = new HashSet();
+
+ var context = new WorkflowGraphNetworkBuilderContext
+ {
+ WorkflowGraphs = workflowGraphs,
+ VisitedNodes = nodes
+ };
+
+ foreach (var workflowGraph in context.WorkflowGraphs)
+ VisitWorkflowGraph(workflowGraph, context);
+
+ return new WorkflowGraphNetwork(nodes);
+ }
+
+ private void VisitWorkflowGraph(WorkflowGraph workflowGraph, WorkflowGraphNetworkBuilderContext context)
+ {
+ var activityNodes = workflowGraph.Nodes;
+ var node = context.VisitedNodes.FirstOrDefault(x => x.WorkflowGraph == workflowGraph);
+
+ if (node == null)
+ {
+ node = new WorkflowGraphNode(workflowGraph);
+ context.VisitedNodes.Add(node);
+ }
+
+ var workflowDefinitionNodes = activityNodes
+ .Where(x => x.Activity is WorkflowDefinitionActivity)
+ .Select(x => (WorkflowDefinitionActivity)x.Activity)
+ .ToList();
+
+ foreach (var workflowDefinitionNode in workflowDefinitionNodes)
+ {
+ VisitConsumingActivityNode(node, workflowDefinitionNode, context);
+ }
+ }
+
+ private void VisitConsumingActivityNode(WorkflowGraphNode node, WorkflowDefinitionActivity workflowDefinitionNode, WorkflowGraphNetworkBuilderContext context)
+ {
+ var consumedWorkflowDefinitionId = workflowDefinitionNode.WorkflowDefinitionId;
+ var consumedWorkflowGraph = context.WorkflowGraphs.FirstOrDefault(x => x.Workflow.Identity.DefinitionId == consumedWorkflowDefinitionId);
+
+ if (consumedWorkflowGraph == null)
+ return;
+
+ var childNode = context.VisitedNodes.FirstOrDefault(x => x.WorkflowGraph == consumedWorkflowGraph);
+
+ if (childNode == null)
+ {
+ childNode = new WorkflowGraphNode(consumedWorkflowGraph);
+ context.VisitedNodes.Add(childNode);
+ VisitWorkflowGraph(childNode.WorkflowGraph, context);
+ }
+
+ node.Successors.Add(childNode);
+ childNode.Predecessors.Add(node);
+ }
+
+ private async Task> GetAllWorkflowGraphsAsync(CancellationToken cancellationToken)
+ {
+ var workflowDefinitionFilter = new WorkflowDefinitionFilter
+ {
+ VersionOptions = VersionOptions.LatestOrPublished
+ };
+ var workflowDefinitionSummaries = await workflowDefinitionStore.FindSummariesAsync(workflowDefinitionFilter, cancellationToken);
+ var workflowGraphs = new List();
+
+ foreach (var workflowDefinitionSummary in workflowDefinitionSummaries)
+ {
+ var workflowGraph = await workflowDefinitionService.FindWorkflowGraphAsync(workflowDefinitionSummary.DefinitionId, VersionOptions.LatestOrPublished, cancellationToken);
+
+ if (workflowGraph != null)
+ workflowGraphs.Add(workflowGraph);
+ }
+
+ return workflowGraphs;
+ }
+
+ private class WorkflowGraphNetworkBuilderContext
+ {
+ public ICollection WorkflowGraphs { get; set; } = new List();
+ public HashSet VisitedNodes { get; set; } = new();
+ }
+}
\ No newline at end of file