diff --git a/src/core/Elsa.Abstractions/Triggers/IGetsTriggersForActivityBlueprintAndWorkflow.cs b/src/core/Elsa.Abstractions/Triggers/IGetsTriggersForActivityBlueprintAndWorkflow.cs
new file mode 100644
index 000000000..8a8e9bf25
--- /dev/null
+++ b/src/core/Elsa.Abstractions/Triggers/IGetsTriggersForActivityBlueprintAndWorkflow.cs
@@ -0,0 +1,27 @@
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Elsa.ActivityProviders;
+using Elsa.Services.Models;
+
+namespace Elsa.Triggers
+{
+ ///
+ /// An object which can get a collection of the for a specified activity blueprint and workflow.
+ ///
+ public interface IGetsTriggersForActivityBlueprintAndWorkflow
+ {
+ ///
+ /// Gets a collection of the workflow triggers for the specified activity blueprint.
+ ///
+ /// An activity blueprint
+ /// A workflow execution context
+ /// A dictionary of all of the activity types (by name)
+ /// An optional cancellation token
+ /// A task exposing a collection of workflow triggers for the activity and workflow.
+ Task> GetTriggersForActivityBlueprintAsync(IActivityBlueprint activityBlueprint,
+ WorkflowExecutionContext workflowExecutionContext,
+ IDictionary activityTypes,
+ CancellationToken cancellationToken = default);
+ }
+}
\ No newline at end of file
diff --git a/src/core/Elsa.Core/Extensions/ElsaServiceCollectionExtensions.cs b/src/core/Elsa.Core/Extensions/ElsaServiceCollectionExtensions.cs
index ee660fcb5..ca7ec6115 100644
--- a/src/core/Elsa.Core/Extensions/ElsaServiceCollectionExtensions.cs
+++ b/src/core/Elsa.Core/Extensions/ElsaServiceCollectionExtensions.cs
@@ -146,6 +146,7 @@ namespace Microsoft.Extensions.DependencyInjection
.AddScoped()
.AddScoped()
.AddScoped()
+ .AddTransient()
.AddSingleton()
.AddScoped()
.AddBookmarkProvider()
diff --git a/src/core/Elsa.Core/Triggers/TriggersForActivityBlueprintAndWorkflowProvider.cs b/src/core/Elsa.Core/Triggers/TriggersForActivityBlueprintAndWorkflowProvider.cs
new file mode 100644
index 000000000..cab1f8bf9
--- /dev/null
+++ b/src/core/Elsa.Core/Triggers/TriggersForActivityBlueprintAndWorkflowProvider.cs
@@ -0,0 +1,89 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Elsa.ActivityProviders;
+using Elsa.Bookmarks;
+using Elsa.Services;
+using Elsa.Services.Models;
+
+namespace Elsa.Triggers
+{
+ ///
+ /// Default implementation of .
+ ///
+ public class TriggersForActivityBlueprintAndWorkflowProvider : IGetsTriggersForActivityBlueprintAndWorkflow
+ {
+ readonly IBookmarkHasher bookmarkHasher;
+ readonly IEnumerable bookmarkProviders;
+ readonly ICreatesActivityExecutionContextForActivityBlueprint activityExecutionContextFactory;
+
+ public TriggersForActivityBlueprintAndWorkflowProvider(IBookmarkHasher bookmarkHasher,
+ IEnumerable bookmarkProviders,
+ ICreatesActivityExecutionContextForActivityBlueprint activityExecutionContextFactory)
+ {
+ this.bookmarkHasher = bookmarkHasher ?? throw new System.ArgumentNullException(nameof(bookmarkHasher));
+ this.bookmarkProviders = bookmarkProviders ?? throw new System.ArgumentNullException(nameof(bookmarkProviders));
+ this.activityExecutionContextFactory = activityExecutionContextFactory ?? throw new System.ArgumentNullException(nameof(activityExecutionContextFactory));
+ }
+
+ ///
+ /// Gets a collection of the workflow triggers for the specified activity blueprint.
+ ///
+ /// An activity blueprint
+ /// A workflow execution context
+ /// A dictionary of all of the activity types (by name)
+ /// An optional cancellation token
+ /// A task exposing a collection of workflow triggers for the activity and workflow.
+ public async Task> GetTriggersForActivityBlueprintAsync(IActivityBlueprint activityBlueprint,
+ WorkflowExecutionContext workflowExecutionContext,
+ IDictionary activityTypes,
+ CancellationToken cancellationToken = default)
+ {
+ var bookmarkProviderContext = GetBookmarkProviderContext(activityBlueprint, workflowExecutionContext, cancellationToken, activityTypes);
+ var supportedBookmarkProviders = await GetSupportedBookmarkProvidersForContextAsync(bookmarkProviderContext)
+ .ToListAsync(cancellationToken);
+
+ var tasksOfListsOfTriggers = supportedBookmarkProviders
+ .Select(async bookmarkProvider => await GetTriggersForBookmarkProvider(bookmarkProvider,
+ bookmarkProviderContext,
+ activityBlueprint,
+ workflowExecutionContext.WorkflowBlueprint,
+ cancellationToken));
+ return (await Task.WhenAll(tasksOfListsOfTriggers))
+ .SelectMany(x => x)
+ .ToList();
+ }
+
+ BookmarkProviderContext GetBookmarkProviderContext(IActivityBlueprint activity,
+ WorkflowExecutionContext workflowExecutionContext,
+ CancellationToken cancellationToken,
+ IDictionary activityTypes)
+ {
+ var activityExecutionContext = activityExecutionContextFactory.CreateActivityExecutionContext(activity,
+ workflowExecutionContext,
+ cancellationToken);
+ var activityType = activityTypes[activity.Type];
+ return new BookmarkProviderContext(activityExecutionContext, activityType, BookmarkIndexingMode.WorkflowBlueprint);
+ }
+
+ async IAsyncEnumerable GetSupportedBookmarkProvidersForContextAsync(BookmarkProviderContext context)
+ {
+ foreach (var provider in bookmarkProviders)
+ if (await provider.SupportsActivityAsync(context))
+ yield return provider;
+ }
+
+ async Task> GetTriggersForBookmarkProvider(IBookmarkProvider provider,
+ BookmarkProviderContext context,
+ IActivityBlueprint activityBlueprint,
+ IWorkflowBlueprint workflowBlueprint,
+ CancellationToken cancellationToken = default)
+ {
+ var bookmarks = (await provider.GetBookmarksAsync(context, cancellationToken)).ToList();
+ return bookmarks
+ .Select(x => new WorkflowTrigger(workflowBlueprint, activityBlueprint.Id, activityBlueprint.Type, bookmarkHasher.Hash(x), x))
+ .ToList();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/core/Elsa.Core/Triggers/TriggersForBlueprintsProvider.cs b/src/core/Elsa.Core/Triggers/TriggersForBlueprintsProvider.cs
index 0a4891621..74e1aa5b4 100644
--- a/src/core/Elsa.Core/Triggers/TriggersForBlueprintsProvider.cs
+++ b/src/core/Elsa.Core/Triggers/TriggersForBlueprintsProvider.cs
@@ -4,7 +4,6 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Elsa.ActivityProviders;
-using Elsa.Bookmarks;
using Elsa.Services;
using Elsa.Services.Models;
@@ -17,22 +16,16 @@ namespace Elsa.Triggers
public class TriggersForBlueprintsProvider : IGetsTriggersForWorkflowBlueprints
{
readonly IActivityTypeService activityTypeService;
- readonly IBookmarkHasher bookmarkHasher;
- readonly IEnumerable bookmarkProviders;
readonly ICreatesWorkflowExecutionContextForWorkflowBlueprint workflowExecutionContextFactory;
- readonly ICreatesActivityExecutionContextForActivityBlueprint activityExecutionContextFactory;
+ readonly IGetsTriggersForActivityBlueprintAndWorkflow triggerProvider;
public TriggersForBlueprintsProvider(IActivityTypeService activityTypeService,
- IBookmarkHasher bookmarkHasher,
- IEnumerable bookmarkProviders,
ICreatesWorkflowExecutionContextForWorkflowBlueprint workflowExecutionContextFactory,
- ICreatesActivityExecutionContextForActivityBlueprint activityExecutionContextFactory)
+ IGetsTriggersForActivityBlueprintAndWorkflow triggerProvider)
{
this.activityTypeService = activityTypeService ?? throw new ArgumentNullException(nameof(activityTypeService));
- this.bookmarkHasher = bookmarkHasher ?? throw new ArgumentNullException(nameof(bookmarkHasher));
- this.bookmarkProviders = bookmarkProviders ?? throw new ArgumentNullException(nameof(bookmarkProviders));
this.workflowExecutionContextFactory = workflowExecutionContextFactory ?? throw new ArgumentNullException(nameof(workflowExecutionContextFactory));
- this.activityExecutionContextFactory = activityExecutionContextFactory ?? throw new ArgumentNullException(nameof(activityExecutionContextFactory));
+ this.triggerProvider = triggerProvider ?? throw new ArgumentNullException(nameof(triggerProvider));
}
///
@@ -52,56 +45,18 @@ namespace Elsa.Triggers
var startingActivityBlueprints = workflowBlueprint.GetStartActivities();
var workflowExecutionContext = await workflowExecutionContextFactory.CreateWorkflowExecutionContextAsync(workflowBlueprint,
cancellationToken);
-
- foreach (var activityBlueprint in startingActivityBlueprints)
- {
- var bookmarkProviderContext = GetBookmarkProviderContext(activityBlueprint, workflowExecutionContext, cancellationToken, activityTypes);
- var supportedBookmarkProviders = await GetSupportedBookmarkProvidersForContextAsync(bookmarkProviderContext).ToListAsync(cancellationToken);
-
- foreach (var bookmarkProvider in supportedBookmarkProviders)
- {
- var triggers = await GetTriggersForBookmarkProvider(bookmarkProvider,
- bookmarkProviderContext,
- activityBlueprint,
- workflowBlueprint,
- cancellationToken);
- allTriggers.AddRange(triggers);
- }
- }
+ var tasksOfCollectionsOfTriggers = startingActivityBlueprints
+ .Select(async activityBlueprint => await triggerProvider.GetTriggersForActivityBlueprintAsync(activityBlueprint,
+ workflowExecutionContext,
+ activityTypes,
+ cancellationToken));
+ var triggers = (await Task.WhenAll(tasksOfCollectionsOfTriggers))
+ .SelectMany(x => x)
+ .ToList();
+ allTriggers.AddRange(triggers);
}
return allTriggers;
}
-
- BookmarkProviderContext GetBookmarkProviderContext(IActivityBlueprint activity,
- WorkflowExecutionContext workflowExecutionContext,
- CancellationToken cancellationToken,
- IDictionary activityTypes)
- {
- var activityExecutionContext = activityExecutionContextFactory.CreateActivityExecutionContext(activity,
- workflowExecutionContext,
- cancellationToken);
- var activityType = activityTypes[activity.Type];
- return new BookmarkProviderContext(activityExecutionContext, activityType, BookmarkIndexingMode.WorkflowBlueprint);
- }
-
- async IAsyncEnumerable GetSupportedBookmarkProvidersForContextAsync(BookmarkProviderContext context)
- {
- foreach (var provider in bookmarkProviders)
- if (await provider.SupportsActivityAsync(context))
- yield return provider;
- }
-
- async Task> GetTriggersForBookmarkProvider(IBookmarkProvider provider,
- BookmarkProviderContext context,
- IActivityBlueprint activityBlueprint,
- IWorkflowBlueprint workflowBlueprint,
- CancellationToken cancellationToken = default)
- {
- var bookmarks = (await provider.GetBookmarksAsync(context, cancellationToken)).ToList();
- return bookmarks
- .Select(x => new WorkflowTrigger(workflowBlueprint, activityBlueprint.Id, activityBlueprint.Type, bookmarkHasher.Hash(x), x))
- .ToList();
- }
}
}
\ No newline at end of file
diff --git a/test/unit/Elsa.UnitTests/Triggers/TriggersForBlueprintsProviderTests.cs b/test/unit/Elsa.UnitTests/Triggers/TriggersForBlueprintsProviderTests.cs
index 77a193e11..f6d2fccaf 100644
--- a/test/unit/Elsa.UnitTests/Triggers/TriggersForBlueprintsProviderTests.cs
+++ b/test/unit/Elsa.UnitTests/Triggers/TriggersForBlueprintsProviderTests.cs
@@ -17,7 +17,7 @@ namespace Elsa.UnitTests.Triggers
{
public class TriggersForBlueprintsProviderTests
{
- [Theory(DisplayName = "The GetTriggersAsync method should return all triggers for the compatible bookmarks of the start activities of the blueprints"), AutoMoqData]
+ [Theory(DisplayName = "The GetTriggersAsync method should return all triggers for the compatible bookmarks of the start activities of the blueprints. This is actually an integration test."), AutoMoqData]
public async Task GetTriggersAsyncGetsAllTriggersForAllBlueprintsStartActivitiesAndCompatibleBookmarks(IActivityTypeService activityTypeService,
IBookmarkHasher bookmarkHasher,
IBookmarkProvider provider1,
@@ -65,13 +65,13 @@ namespace Elsa.UnitTests.Triggers
{
var workflowExecutionContextFactory = new WorkflowExecutionContextForWorkflowBlueprintFactory(serviceProvider, workflowFactory);
var activityExecutionContextFactory = new ActivityExecutionContextForActivityBlueprintFactory(serviceProvider);
+ var triggersForActivityProvider = new TriggersForActivityBlueprintAndWorkflowProvider(bookmarkHasher,
+ new[] { provider1, provider2, provider3 },
+ activityExecutionContextFactory);
- // Unfortunately the SUT can't be created by Autofixture because of the IEnumerable in the ctor
var sut = new TriggersForBlueprintsProvider(activityTypeService,
- bookmarkHasher,
- new[] { provider1, provider2, provider3 },
workflowExecutionContextFactory,
- activityExecutionContextFactory);
+ triggersForActivityProvider);
Mock.Get(activityTypeService)
.Setup(x => x.GetActivityTypesAsync(default))