diff --git a/Elsa.sln b/Elsa.sln index 7682d09c5..07e55704e 100644 --- a/Elsa.sln +++ b/Elsa.sln @@ -18,12 +18,6 @@ EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{0354F050-3992-4DD4-B0EE-5FBA04AC72B6}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "architecture", "architecture", "{A34FD350-79C5-492A-8811-6DBD80830F8B}" -ProjectSection(SolutionItems) = preProject - docs\architecture\Layer1.md = docs\architecture\Layer1.md - docs\architecture\Layer2.md = docs\architecture\Layer2.md -EndProjectSection -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "console", "console", "{873BFC3E-63C2-4495-A503-5EC05DCD84E4}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "aspnet", "aspnet", "{56C2FFB8-EA54-45B5-A095-4A78142EB4B5}" @@ -211,7 +205,6 @@ Global {155227F0-A33B-40AA-A4B4-06F813EB921B} = {61017E64-6D00-49CB-9E81-5002DC8F7D5F} {C6658DE0-2B2F-47F0-BB61-2CA66D435C09} = {61017E64-6D00-49CB-9E81-5002DC8F7D5F} {6FA9ED7D-2D32-46BC-B47F-E503B2A4C0A9} = {C6658DE0-2B2F-47F0-BB61-2CA66D435C09} - {A34FD350-79C5-492A-8811-6DBD80830F8B} = {0354F050-3992-4DD4-B0EE-5FBA04AC72B6} {873BFC3E-63C2-4495-A503-5EC05DCD84E4} = {155227F0-A33B-40AA-A4B4-06F813EB921B} {B44A9DDA-8091-490A-BC0B-2EAE4A601B09} = {873BFC3E-63C2-4495-A503-5EC05DCD84E4} {56C2FFB8-EA54-45B5-A095-4A78142EB4B5} = {155227F0-A33B-40AA-A4B4-06F813EB921B} diff --git a/src/core/Elsa.Core/Activities/Console/WriteLine.cs b/src/core/Elsa.Core/Activities/Console/WriteLine.cs index d41206188..eb3d5bd93 100644 --- a/src/core/Elsa.Core/Activities/Console/WriteLine.cs +++ b/src/core/Elsa.Core/Activities/Console/WriteLine.cs @@ -1,4 +1,5 @@ using System.ComponentModel; +using Elsa.Attributes; using Elsa.Models; namespace Elsa.Activities.Console; diff --git a/src/core/Elsa.Core/Attributes/ActivityAttribute.cs b/src/core/Elsa.Core/Attributes/ActivityAttribute.cs index 434fe631a..98c36630f 100644 --- a/src/core/Elsa.Core/Attributes/ActivityAttribute.cs +++ b/src/core/Elsa.Core/Attributes/ActivityAttribute.cs @@ -3,13 +3,29 @@ namespace Elsa.Attributes; [AttributeUsage(AttributeTargets.Class)] public class ActivityAttribute : Attribute { - public ActivityAttribute(string? typeName = default, string? description = default, string? category = default) + public ActivityAttribute(string @namespace, string? category, string? description = default) { + Namespace = @namespace; + Description = description; + Category = category; + } + + public ActivityAttribute(string @namespace, string? description = default) + { + Namespace = @namespace; + Description = description; + Category = @namespace; + } + + public ActivityAttribute(string @namespace, string? typeName, string? description = default, string? category = default) + { + Namespace = @namespace; TypeName = typeName; Description = description; Category = category; } - + + public string? Namespace { get; } public string? TypeName { get; } public string? Description { get; } public string? Category { get; } diff --git a/src/core/Elsa.Core/Attributes/InputAttribute.cs b/src/core/Elsa.Core/Attributes/InputAttribute.cs index 40fd569d7..b67c8e8dd 100644 --- a/src/core/Elsa.Core/Attributes/InputAttribute.cs +++ b/src/core/Elsa.Core/Attributes/InputAttribute.cs @@ -25,7 +25,7 @@ public class InputAttribute : Attribute // /// // /// A brief description about this property for workflow tooling to use when displaying activity editors. // /// - // public string? Description { get; set; } + public string? Description { get; set; } /// /// A category to group this property with. @@ -68,7 +68,7 @@ public class InputAttribute : Attribute public string[]? SupportedSyntaxes { get; set; } /// - /// A value indicating whether this property should be displayed but as read-only. + /// A value indicating whether this property should be displayed as read-only. /// public bool IsReadOnly { get; set; } diff --git a/src/core/Elsa.Core/Extensions/ActivityExecutionContextExtensions.cs b/src/core/Elsa.Core/Extensions/ActivityExecutionContextExtensions.cs index a7766e94c..59b8f2c46 100644 --- a/src/core/Elsa.Core/Extensions/ActivityExecutionContextExtensions.cs +++ b/src/core/Elsa.Core/Extensions/ActivityExecutionContextExtensions.cs @@ -1,9 +1,24 @@ -using System.Text.Json; +using Elsa.Contracts; using Elsa.Models; namespace Elsa.Extensions; public static class ActivityExecutionContextExtensions { - public static bool TryGetInput(this ActivityExecutionContext context, string key, out T value) => context.Input.TryGetValue(key, out value); + public static bool TryGetInput(this ActivityExecutionContext context, string key, out T value) => context.Input.TryGetValue(key, out value!); + public static T GetInput(this ActivityExecutionContext context) => context.GetInput(typeof(T).Name); + public static T GetInput(this ActivityExecutionContext context, string key) => (T)context.Input[key]; + + public static WorkflowExecutionLogEntry AddExecutionLogEntry(this ActivityExecutionContext context, string eventName, string? message = default, object? payload = default) => + context.AddExecutionLogEntry(eventName, message, default, payload); + + public static WorkflowExecutionLogEntry AddExecutionLogEntry(this ActivityExecutionContext context, string eventName, string? message = default, string? source = default, object? payload = default) + { + var activity = context.Activity; + var workflowExecutionContext = context.WorkflowExecutionContext; + var now = context.GetRequiredService().UtcNow; + var logEntry = new WorkflowExecutionLogEntry(activity.Id, activity.TypeName, now, eventName, message, source, payload); + workflowExecutionContext.ExecutionLog.Add(logEntry); + return logEntry; + } } \ No newline at end of file diff --git a/src/core/Elsa.Core/Models/ActivityExecutionContext.cs b/src/core/Elsa.Core/Models/ActivityExecutionContext.cs index 7737690e8..db89525ae 100644 --- a/src/core/Elsa.Core/Models/ActivityExecutionContext.cs +++ b/src/core/Elsa.Core/Models/ActivityExecutionContext.cs @@ -62,7 +62,7 @@ public class ActivityExecutionContext /// A dictionary of received inputs. /// public IReadOnlyDictionary Input => WorkflowExecutionContext.Input; - + /// /// Journal data will be added to the workflow execution log for the "Executed" event. /// @@ -98,10 +98,12 @@ public class ActivityExecutionContext CreateBookmark(bookmarkDatum, callback); } - public void CreateBookmarks(IEnumerable bookmarks) => _bookmarks.AddRange(bookmarks); - public void CreateBookmark(Bookmark bookmark) => _bookmarks.Add(bookmark); + public void AddBookmarks(IEnumerable bookmarks) => _bookmarks.AddRange(bookmarks); + public void AddBookmark(Bookmark bookmark) => _bookmarks.Add(bookmark); - public void CreateBookmark(object? bookmarkDatum, ExecuteActivityDelegate? callback = default) + public Bookmark CreateBookmark(ExecuteActivityDelegate callback) => CreateBookmark(default, callback); + + public Bookmark CreateBookmark(object? bookmarkDatum = default, ExecuteActivityDelegate? callback = default) { var hasher = GetRequiredService(); var identityGenerator = GetRequiredService(); @@ -109,17 +111,20 @@ public class ActivityExecutionContext var bookmarkDatumJson = bookmarkDatum != null ? bookmarkDataSerializer.Serialize(bookmarkDatum) : default; var hash = bookmarkDatumJson != null ? hasher.Hash(bookmarkDatumJson) : default; - CreateBookmark(new Bookmark( + var bookmark = new Bookmark( identityGenerator.GenerateId(), Activity.TypeName, hash, bookmarkDatumJson, Activity.Id, Id, - callback?.Method.Name)); + callback?.Method.Name); + + AddBookmark(bookmark); + return bookmark; } - public T? GetProperty(string key) => Properties.TryGetValue(key, out var value) ? value : default; + public T? GetProperty(string key) => Properties!.TryGetValue(key, out var value) ? value : default; public void SetProperty(string key, T value) where T : notnull => Properties[key] = value; public T UpdateProperty(string key, Func updater) where T : notnull diff --git a/src/core/Elsa.Core/Models/ExpressionExecutionContext.cs b/src/core/Elsa.Core/Models/ExpressionExecutionContext.cs index e86e9cbd0..ef3faa107 100644 --- a/src/core/Elsa.Core/Models/ExpressionExecutionContext.cs +++ b/src/core/Elsa.Core/Models/ExpressionExecutionContext.cs @@ -26,7 +26,24 @@ public class ExpressionExecutionContext public object Get(RegisterLocationReference locationReference) => GetLocation(locationReference).Value!; public T Get(RegisterLocationReference locationReference) => (T)Get(locationReference); public T? Get(Input? input) => input != null ? (T?)GetLocation(input.LocationReference).Value : default; - public T? GetVariable(string name, object? defaultValue = default) => Get(new Variable(name, defaultValue)); + public T? GetVariable(string name) => (T?)GetVariable(name); + public T? GetVariable() => (T?)GetVariable(typeof(T).Name); + + public object? GetVariable(string name) + { + var variable = Workflow.Variables.FirstOrDefault(x => x.Name == name); + return variable?.Get(Register); + } + + public Variable SetVariable(T? value) => SetVariable(typeof(T).Name, value); + public Variable SetVariable(string name, T? value) => SetVariable(name, (object?)value); + + public Variable SetVariable(string name, object? value) + { + var variable = Workflow.Variables.FirstOrDefault(x => x.Name == name) ?? new Variable(name, value); + variable.Set(Register, value); + return variable; + } public void Set(RegisterLocationReference locationReference, object? value) { diff --git a/src/core/Elsa.Core/Models/RegisterLocationReference.cs b/src/core/Elsa.Core/Models/RegisterLocationReference.cs index fa8d54672..361df7e6d 100644 --- a/src/core/Elsa.Core/Models/RegisterLocationReference.cs +++ b/src/core/Elsa.Core/Models/RegisterLocationReference.cs @@ -10,10 +10,13 @@ public abstract class RegisterLocationReference public string Id { get; set; } = default!; public abstract RegisterLocation Declare(); + public object? Get(Register register) => GetLocation(register).Value; + public T? Get(Register register) => (T?)Get(register); public object? Get(ExpressionExecutionContext context) => context.Get(this); public object? Get(ActivityExecutionContext context) => Get(context.ExpressionExecutionContext); public T? Get(ExpressionExecutionContext context) => (T?)Get(context); public T? Get(ActivityExecutionContext context) => (T?)Get(context.ExpressionExecutionContext); + public void Set(Register register, object? value) => GetLocation(register).Value = value; public void Set(ExpressionExecutionContext context, object? value) => context.Set(this, value); public void Set(ActivityExecutionContext context, object? value) => Set(context.ExpressionExecutionContext, value); diff --git a/src/core/Elsa.Core/Models/WorkflowExecutionContext.cs b/src/core/Elsa.Core/Models/WorkflowExecutionContext.cs index 77a9e29f2..0ce6ae4c7 100644 --- a/src/core/Elsa.Core/Models/WorkflowExecutionContext.cs +++ b/src/core/Elsa.Core/Models/WorkflowExecutionContext.cs @@ -37,10 +37,12 @@ public class WorkflowExecutionContext CancellationToken = cancellationToken; NodeIdLookup = _nodes.ToDictionary(x => x.NodeId); NodeActivityLookup = _nodes.ToDictionary(x => x.Activity); + Register = workflow.CreateRegister(); } public Workflow Workflow { get; } - public ActivityNode Graph { get; set; } + public ActivityNode Graph { get; } + public Register Register { get; } public string Id { get; set; } public IReadOnlyCollection Nodes => new ReadOnlyCollection(_nodes); public IDictionary NodeIdLookup { get; } @@ -48,18 +50,18 @@ public class WorkflowExecutionContext public IActivityScheduler Scheduler { get; } public Bookmark? Bookmark { get; } public IReadOnlyDictionary Input { get; } - + /// /// A dictionary that can be used by application code and activities to store information. Values need to be serializable, since this dictionary will be persisted alongside the workflow instance. /// public IDictionary Properties { get; set; } = new Dictionary(); - + /// /// A dictionary that can be used by application code and middleware to store information and even services. Values do not need to be serializable, since this dictionary will not be persisted. /// All data will be gone once workflow execution completes. /// public IDictionary TransientProperties { get; set; } = new Dictionary(); - + public ExecuteActivityDelegate? ExecuteDelegate { get; set; } public CancellationToken CancellationToken { get; } public IReadOnlyCollection Bookmarks => new ReadOnlyCollection(_bookmarks); @@ -99,7 +101,7 @@ public class WorkflowExecutionContext RemoveCompletionCallback(entry); return entry.CompletionCallback; } - + public void RemoveCompletionCallback(ActivityCompletionCallbackEntry entry) => _completionCallbackEntries.Remove(entry); public ActivityNode FindNodeById(string nodeId) => NodeIdLookup[nodeId]; @@ -141,8 +143,27 @@ public class WorkflowExecutionContext var activityInvoker = GetRequiredService(); var workItem = new ActivityWorkItem(bookmarkedActivity.Id, async () => await activityInvoker.InvokeAsync(bookmarkedActivityContext)); Scheduler.Push(workItem); - + // If no resumption point was specified, use Noop to prevent the regular "ExecuteAsync" method to be invoked. ExecuteDelegate = bookmark.CallbackMethodName != null ? bookmarkedActivity.GetResumeActivityDelegate(bookmark.CallbackMethodName) : Noop; } + + public T? GetVariable(string name) => (T?)GetVariable(name); + public T? GetVariable() => (T?)GetVariable(typeof(T).Name); + + public object? GetVariable(string name) + { + var variable = Workflow.Variables.FirstOrDefault(x => x.Name == name); + return variable?.Get(Register); + } + + public Variable SetVariable(T? value) => SetVariable(typeof(T).Name, value); + public Variable SetVariable(string name, T? value) => SetVariable(name, (object?)value); + + public Variable SetVariable(string name, object? value) + { + var variable = Workflow.Variables.FirstOrDefault(x => x.Name == name) ?? new Variable(name, value); + variable.Set(Register, value); + return variable; + } } \ No newline at end of file diff --git a/src/core/Elsa.Core/Pipelines/ActivityExecution/Components/ActivityInvokerMiddleware.cs b/src/core/Elsa.Core/Pipelines/ActivityExecution/Components/ActivityInvokerMiddleware.cs index b8597f091..e0c65b7c2 100644 --- a/src/core/Elsa.Core/Pipelines/ActivityExecution/Components/ActivityInvokerMiddleware.cs +++ b/src/core/Elsa.Core/Pipelines/ActivityExecution/Components/ActivityInvokerMiddleware.cs @@ -64,13 +64,7 @@ public class ActivityInvokerMiddleware : IActivityExecutionMiddleware await CompleteParentsAsync(context); } - private void LogExecutionRecord(ActivityExecutionContext context, string eventName, string? message = default, string? source = default, object? payload = default) - { - var activity = context.Activity; - var workflowExecutionContext = context.WorkflowExecutionContext; - var logEntry = new WorkflowExecutionLogEntry(activity.Id, activity.TypeName, _clock.UtcNow, eventName, message, source, payload); - workflowExecutionContext.ExecutionLog.Add(logEntry); - } + private void LogExecutionRecord(ActivityExecutionContext context, string eventName, string? message = default, string? source = default, object? payload = default) => context.AddExecutionLogEntry(eventName, message, source, payload); private async Task EvaluateInputPropertiesAsync(ActivityExecutionContext context) { diff --git a/src/core/Elsa.Core/Services/ActivityInvoker.cs b/src/core/Elsa.Core/Services/ActivityInvoker.cs index 11a2b1f81..9c6f9eed6 100644 --- a/src/core/Elsa.Core/Services/ActivityInvoker.cs +++ b/src/core/Elsa.Core/Services/ActivityInvoker.cs @@ -26,8 +26,7 @@ public class ActivityInvoker : IActivityInvoker var parentActivityExecutionContext = owner; // Setup an activity execution context. - var register = workflowExecutionContext.Workflow.CreateRegister(); - + var register = workflowExecutionContext.Register; var workflow = workflowExecutionContext.Workflow; var transientProperties = workflowExecutionContext.TransientProperties; var expressionExecutionContext = new ExpressionExecutionContext(_serviceProvider, register, workflow, transientProperties, parentActivityExecutionContext?.ExpressionExecutionContext, cancellationToken); diff --git a/src/core/Elsa.Management/Services/ActivityDescriber.cs b/src/core/Elsa.Management/Services/ActivityDescriber.cs index 84056ed89..c5add7090 100644 --- a/src/core/Elsa.Management/Services/ActivityDescriber.cs +++ b/src/core/Elsa.Management/Services/ActivityDescriber.cs @@ -88,13 +88,13 @@ public class ActivityDescriber : IActivityDescriber wrappedPropertyType, GetUIHint(wrappedPropertyType, inputAttribute), inputAttribute?.DisplayName ?? propertyInfo.Name.Humanize(LetterCasing.Title), - descriptionAttribute?.Description, + descriptionAttribute?.Description ?? inputAttribute?.Description, _optionsResolver.GetOptions(propertyInfo), inputAttribute?.Category, inputAttribute?.Order ?? 0, _defaultValueResolver.GetDefaultValue(propertyInfo), inputAttribute?.DefaultSyntax, - //inputAttribute?.SupportedSyntaxes, TODO: Come up with a different way to specify support languages for activity inputs. By default, maybe all pros should support all registered scripting languages? + //inputAttribute?.SupportedSyntaxes, TODO: Come up with a different way to specify support languages for activity inputs. By default, maybe all props should support all registered scripting languages? inputAttribute?.IsReadOnly ?? false, inputAttribute?.IsBrowsable ?? true ); diff --git a/src/modules/Elsa.Modules.WorkflowContexts/Extensions/WorkflowExecutionContextExtensions.cs b/src/modules/Elsa.Modules.WorkflowContexts/Extensions/WorkflowExecutionContextExtensions.cs new file mode 100644 index 000000000..2c4bfe843 --- /dev/null +++ b/src/modules/Elsa.Modules.WorkflowContexts/Extensions/WorkflowExecutionContextExtensions.cs @@ -0,0 +1,27 @@ +using Elsa.Extensions; +using Elsa.Models; +using Elsa.Modules.WorkflowContexts.Models; + +namespace Elsa.Modules.WorkflowContexts.Extensions; + +public static class WorkflowExecutionContextExtensions +{ + public static void SetWorkflowContext(this WorkflowExecutionContext workflowExecutionContext, WorkflowContext workflowContext, object? value) => workflowExecutionContext.TransientProperties.SetWorkflowContext(workflowContext, value); + public static void SetWorkflowContext(this ExpressionExecutionContext expressionExecutionContext, WorkflowContext workflowContext, object? value) => expressionExecutionContext.TransientProperties.SetWorkflowContext(workflowContext, value); + public static T? GetWorkflowContext(this WorkflowExecutionContext workflowExecutionContext) => (T?)workflowExecutionContext.GetWorkflowContext(new WorkflowContext(typeof(TProvider))); + public static T? GetWorkflowContext(this ExpressionExecutionContext expressionExecutionContext) => (T?)expressionExecutionContext.TransientProperties.GetWorkflowContext(new WorkflowContext(typeof(TProvider))); + public static object? GetWorkflowContext(this WorkflowExecutionContext workflowExecutionContext, WorkflowContext workflowContext) => workflowExecutionContext.TransientProperties.GetWorkflowContext(workflowContext); + public static object? GetWorkflowContext(this ExpressionExecutionContext expressionExecutionContext, WorkflowContext workflowContext) => expressionExecutionContext.TransientProperties.GetWorkflowContext(workflowContext); + + private static void SetWorkflowContext(this IDictionary transientProperties, WorkflowContext workflowContext, object? value) + { + var contextDictionary = transientProperties.GetOrAdd("WorkflowContexts", () => new Dictionary()); + contextDictionary[workflowContext.ProviderType] = value; + } + + private static object? GetWorkflowContext(this IDictionary transientProperties, WorkflowContext workflowContext) + { + var contextDictionary = transientProperties.GetOrAdd("WorkflowContexts", () => new Dictionary()); + return contextDictionary[workflowContext.ProviderType]; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Modules.WorkflowContexts/Middleware/WorkflowContextMiddleware.cs b/src/modules/Elsa.Modules.WorkflowContexts/Middleware/WorkflowContextMiddleware.cs index 04e05b926..9796ef7fa 100644 --- a/src/modules/Elsa.Modules.WorkflowContexts/Middleware/WorkflowContextMiddleware.cs +++ b/src/modules/Elsa.Modules.WorkflowContexts/Middleware/WorkflowContextMiddleware.cs @@ -1,6 +1,7 @@ using Elsa.Extensions; using Elsa.Models; using Elsa.Modules.WorkflowContexts.Contracts; +using Elsa.Modules.WorkflowContexts.Extensions; using Elsa.Modules.WorkflowContexts.Models; using Elsa.Pipelines.WorkflowExecution; using Elsa.Pipelines.WorkflowExecution.Components; @@ -36,8 +37,7 @@ public class WorkflowContextMiddleware : WorkflowExecutionMiddleware var value = await provider.LoadAsync(context); // Store the loaded value into the workflow execution context. - var contextDictionary = context.TransientProperties.GetOrAdd("WorkflowContexts", () => new Dictionary()); - contextDictionary.Add(workflowContext, value); + context.SetWorkflowContext(workflowContext, value); } // Invoke the next middleware. @@ -47,8 +47,7 @@ public class WorkflowContextMiddleware : WorkflowExecutionMiddleware foreach (var workflowContext in workflowContexts!) { // Get the loaded value from the workflow execution context. - var contextDictionary = context.TransientProperties.GetOrAdd("WorkflowContexts", () => new Dictionary()); - var value = contextDictionary[workflowContext]; + var value = context.GetWorkflowContext(workflowContext); var provider = (IWorkflowContextProvider)ActivatorUtilities.GetServiceOrCreateInstance(_serviceProvider, workflowContext.ProviderType); await provider.SaveAsync(context, value); diff --git a/src/persistence/Elsa.Persistence.Abstractions/Requests/FindWorkflowBookmark.cs b/src/persistence/Elsa.Persistence.Abstractions/Requests/FindWorkflowBookmark.cs new file mode 100644 index 000000000..db0c5866e --- /dev/null +++ b/src/persistence/Elsa.Persistence.Abstractions/Requests/FindWorkflowBookmark.cs @@ -0,0 +1,6 @@ +using Elsa.Mediator.Contracts; +using Elsa.Persistence.Entities; + +namespace Elsa.Persistence.Requests; + +public record FindWorkflowBookmark(string BookmarkId) : IRequest; \ No newline at end of file diff --git a/src/persistence/Elsa.Persistence.EntityFrameworkCore/Handlers/Requests/FindWorkflowBookmarkHandler.cs b/src/persistence/Elsa.Persistence.EntityFrameworkCore/Handlers/Requests/FindWorkflowBookmarkHandler.cs new file mode 100644 index 000000000..f4e51e778 --- /dev/null +++ b/src/persistence/Elsa.Persistence.EntityFrameworkCore/Handlers/Requests/FindWorkflowBookmarkHandler.cs @@ -0,0 +1,13 @@ +using Elsa.Mediator.Contracts; +using Elsa.Persistence.Entities; +using Elsa.Persistence.EntityFrameworkCore.Contracts; +using Elsa.Persistence.Requests; + +namespace Elsa.Persistence.EntityFrameworkCore.Handlers.Requests; + +public class FindWorkflowBookmarkHandler : IRequestHandler +{ + private readonly IStore _store; + public FindWorkflowBookmarkHandler(IStore store) => _store = store; + public async Task HandleAsync(FindWorkflowBookmark request, CancellationToken cancellationToken) => await _store.FindAsync(x => x.Id == request.BookmarkId, cancellationToken); +} \ No newline at end of file diff --git a/src/persistence/Elsa.Persistence.InMemory/Handlers/Requests/FindWorkflowBookmarkHandler.cs b/src/persistence/Elsa.Persistence.InMemory/Handlers/Requests/FindWorkflowBookmarkHandler.cs new file mode 100644 index 000000000..86d7c7e7c --- /dev/null +++ b/src/persistence/Elsa.Persistence.InMemory/Handlers/Requests/FindWorkflowBookmarkHandler.cs @@ -0,0 +1,16 @@ +using System.Threading; +using System.Threading.Tasks; +using Elsa.Mediator.Contracts; +using Elsa.Persistence.Entities; +using Elsa.Persistence.InMemory.Services; +using Elsa.Persistence.Requests; + +namespace Elsa.Persistence.InMemory.Handlers.Requests; + +public class FindWorkflowBookmarkHandler : IRequestHandler +{ + private readonly InMemoryStore _store; + public FindWorkflowBookmarkHandler(InMemoryStore store) => _store = store; + public Task HandleAsync(FindWorkflowBookmark request, CancellationToken cancellationToken) => Task.FromResult(FindById(request.BookmarkId)); + private WorkflowBookmark? FindById(string id) => _store.Find(x => x.Id == id); +} \ No newline at end of file diff --git a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/WorkflowContextsWorkflow.cs b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/WorkflowContextsWorkflow.cs index 3b423e342..ee8f2e85d 100644 --- a/src/samples/aspnet/Elsa.Samples.Web1/Workflows/WorkflowContextsWorkflow.cs +++ b/src/samples/aspnet/Elsa.Samples.Web1/Workflows/WorkflowContextsWorkflow.cs @@ -4,7 +4,6 @@ using Elsa.Contracts; using Elsa.Models; using Elsa.Modules.WorkflowContexts.Abstractions; using Elsa.Modules.WorkflowContexts.Extensions; -using Elsa.Modules.WorkflowContexts.Models; using Elsa.Runtime.Contracts; namespace Elsa.Samples.Web1.Workflows;