diff --git a/src/clients/Elsa.Api.Client/Extensions/JsonObjectExtensions.cs b/src/clients/Elsa.Api.Client/Extensions/JsonObjectExtensions.cs index 3653519b9..5b4ad7e9c 100644 --- a/src/clients/Elsa.Api.Client/Extensions/JsonObjectExtensions.cs +++ b/src/clients/Elsa.Api.Client/Extensions/JsonObjectExtensions.cs @@ -160,7 +160,7 @@ public static class JsonObjectExtensions { return model.GetProperty(path); } - catch (Exception e) + catch (Exception) { return default; } diff --git a/src/common/Elsa.Mediator/Contracts/ICommandSender.cs b/src/common/Elsa.Mediator/Contracts/ICommandSender.cs index 5373afb3b..02d32ca7a 100644 --- a/src/common/Elsa.Mediator/Contracts/ICommandSender.cs +++ b/src/common/Elsa.Mediator/Contracts/ICommandSender.cs @@ -28,7 +28,7 @@ public interface ICommandSender /// The cancellation token. /// The type of the result. /// The result. - Task SendAsync(ICommand command, ICommandStrategy strategy, CancellationToken cancellationToken = default); + Task SendAsync(ICommand command, ICommandStrategy? strategy, CancellationToken cancellationToken = default); /// /// Sends a command using the specified strategy. @@ -39,7 +39,7 @@ public interface ICommandSender /// The cancellation token. /// The type of the result. /// The result. - Task SendAsync(ICommand command, ICommandStrategy strategy, IDictionary headers, CancellationToken cancellationToken = default); + Task SendAsync(ICommand command, ICommandStrategy? strategy, IDictionary headers, CancellationToken cancellationToken = default); /// /// Sends a command using the default strategy. @@ -54,7 +54,7 @@ public interface ICommandSender /// The command to send. /// The command strategy to use. /// The cancellation token. - Task SendAsync(ICommand command, ICommandStrategy strategy, CancellationToken cancellationToken = default); + Task SendAsync(ICommand command, ICommandStrategy? strategy, CancellationToken cancellationToken = default); /// /// Sends a command using the specified strategy. @@ -63,5 +63,5 @@ public interface ICommandSender /// The command strategy to use. /// Any headers to pass along. /// The cancellation token. - Task SendAsync(ICommand command, ICommandStrategy strategy, IDictionary headers, CancellationToken cancellationToken = default); + Task SendAsync(ICommand command, ICommandStrategy? strategy, IDictionary headers, CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/common/Elsa.Mediator/Extensions/MediatorExtensions.cs b/src/common/Elsa.Mediator/Extensions/MediatorExtensions.cs index e1b307658..69328381c 100644 --- a/src/common/Elsa.Mediator/Extensions/MediatorExtensions.cs +++ b/src/common/Elsa.Mediator/Extensions/MediatorExtensions.cs @@ -39,7 +39,7 @@ public static class MediatorExtensions /// The cancellation token. public static async Task SendAsync(this IMediator mediator, ICommand command, CancellationToken cancellationToken = default) { - await mediator.SendAsync(command, default, cancellationToken); + await mediator.SendAsync(command, null, cancellationToken); } /// @@ -50,6 +50,6 @@ public static class MediatorExtensions /// The cancellation token. public static async Task SendAsync(this ICommandSender commandSender, ICommand command, CancellationToken cancellationToken = default) { - await commandSender.SendAsync(command, default, cancellationToken); + await commandSender.SendAsync(command, null, cancellationToken); } } \ No newline at end of file diff --git a/src/common/Elsa.Mediator/Services/DefaultMediator.cs b/src/common/Elsa.Mediator/Services/DefaultMediator.cs index 3428e283f..96744ec57 100644 --- a/src/common/Elsa.Mediator/Services/DefaultMediator.cs +++ b/src/common/Elsa.Mediator/Services/DefaultMediator.cs @@ -54,9 +54,10 @@ public class DefaultMediator : IMediator return (T)context.Response; } - public async Task SendAsync(ICommand command, ICommandStrategy strategy, IDictionary headers, CancellationToken cancellationToken = default) + public async Task SendAsync(ICommand command, ICommandStrategy? strategy, IDictionary headers, CancellationToken cancellationToken = default) { var resultType = typeof(T); + strategy ??= _defaultCommandStrategy; var context = new CommandContext(command, strategy, resultType, headers, _serviceProvider, cancellationToken); await _commandPipeline.InvokeAsync(context); @@ -92,7 +93,7 @@ public class DefaultMediator : IMediator } /// - public Task SendAsync(ICommand command, ICommandStrategy strategy, CancellationToken cancellationToken = default) + public Task SendAsync(ICommand command, ICommandStrategy? strategy, CancellationToken cancellationToken = default) { return SendAsync(command, strategy, new Dictionary(), cancellationToken); } diff --git a/src/common/Elsa.Testing.Shared.Integration/DispatchWorkflowExtensions.cs b/src/common/Elsa.Testing.Shared.Integration/DispatchWorkflowExtensions.cs index 578802abd..df3436068 100644 --- a/src/common/Elsa.Testing.Shared.Integration/DispatchWorkflowExtensions.cs +++ b/src/common/Elsa.Testing.Shared.Integration/DispatchWorkflowExtensions.cs @@ -63,7 +63,7 @@ public static class DispatchWorkflowExtensions var workflowDispatcher = serviceProvider.GetRequiredService(); var dispatchWorkflowResponse = await workflowDispatcher.DispatchAsync(new DispatchWorkflowDefinitionRequest { - DefinitionVersionId = workflow.DefinitionHandle.DefinitionVersionId, + DefinitionVersionId = workflow.DefinitionHandle.DefinitionVersionId!, InstanceId = instanceId ?? Guid.NewGuid().ToString(), }); dispatchWorkflowResponse.ThrowIfFailed(); diff --git a/src/common/Elsa.Testing.Shared/XunitLogger.cs b/src/common/Elsa.Testing.Shared/XunitLogger.cs index 08c947157..e02d37fb5 100644 --- a/src/common/Elsa.Testing.Shared/XunitLogger.cs +++ b/src/common/Elsa.Testing.Shared/XunitLogger.cs @@ -3,33 +3,24 @@ using Xunit.Abstractions; namespace Elsa.Testing.Shared; -public class XunitLogger : ILogger +public class XunitLogger(ITestOutputHelper testOutputHelper, string categoryName) : ILogger { - private readonly ITestOutputHelper _testOutputHelper; - private readonly string _categoryName; - - public XunitLogger(ITestOutputHelper testOutputHelper, string categoryName) - { - _testOutputHelper = testOutputHelper; - _categoryName = categoryName; - } - - public IDisposable BeginScope(TState state) => NoopDisposable.Instance; + public IDisposable BeginScope(TState state) where TState : notnull => NoopDisposable.Instance; public bool IsEnabled(LogLevel logLevel) => true; public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) { - _testOutputHelper.WriteLine($"{_categoryName} [{eventId}] {formatter(state, exception)}"); + testOutputHelper.WriteLine($"{categoryName} [{eventId}] {formatter(state, exception)}"); if (exception != null) - _testOutputHelper.WriteLine(exception.ToString()); + testOutputHelper.WriteLine(exception.ToString()); } private class NoopDisposable : IDisposable { - public static readonly NoopDisposable Instance = new NoopDisposable(); + public static readonly NoopDisposable Instance = new(); public void Dispose() { diff --git a/src/modules/Elsa.Expressions.Liquid/Helpers/ConfigurationSectionWrapper.cs b/src/modules/Elsa.Expressions.Liquid/Helpers/ConfigurationSectionWrapper.cs index 894e3d85e..3533f98d3 100644 --- a/src/modules/Elsa.Expressions.Liquid/Helpers/ConfigurationSectionWrapper.cs +++ b/src/modules/Elsa.Expressions.Liquid/Helpers/ConfigurationSectionWrapper.cs @@ -2,16 +2,9 @@ namespace Elsa.Expressions.Liquid.Helpers; -public class ConfigurationSectionWrapper +public class ConfigurationSectionWrapper(IConfigurationSection section) { - private readonly IConfigurationSection _section; + public override string ToString() => section.Value!; - public ConfigurationSectionWrapper(IConfigurationSection section) - { - _section = section; - } - - public override string ToString() => _section.Value; - - public ConfigurationSectionWrapper GetSection(string name) => new(_section.GetSection(name)); + public ConfigurationSectionWrapper GetSection(string name) => new(section.GetSection(name)); } \ No newline at end of file diff --git a/src/modules/Elsa.Http/Activities/HttpEndpoint.cs b/src/modules/Elsa.Http/Activities/HttpEndpoint.cs index 6b6590aac..c1a583ed5 100644 --- a/src/modules/Elsa.Http/Activities/HttpEndpoint.cs +++ b/src/modules/Elsa.Http/Activities/HttpEndpoint.cs @@ -461,7 +461,7 @@ public class HttpEndpoint : Trigger var contentType = httpRequest.ContentType!; var headers = httpRequest.Headers.ToDictionary(x => x.Key, x => x.Value.ToArray()); - return await context.ParseContentAsync(contentStream, contentType, targetType, headers, cancellationToken); + return await context.ParseContentAsync(contentStream, contentType, targetType, headers!, cancellationToken); } private static bool HasContent(HttpRequest httpRequest) => httpRequest.Headers.ContentLength > 0; diff --git a/src/modules/Elsa.Http/Activities/SendHttpRequestBase.cs b/src/modules/Elsa.Http/Activities/SendHttpRequestBase.cs index 34e90abc7..bb8930ab5 100644 --- a/src/modules/Elsa.Http/Activities/SendHttpRequestBase.cs +++ b/src/modules/Elsa.Http/Activities/SendHttpRequestBase.cs @@ -240,8 +240,8 @@ public abstract class SendHttpRequestBase(string? source = null, int? line = nul _ => typeof(string) }; - var contentHeadersDictionary = contentHeaders.ToDictionary(x => x.Key, x => x.Value.Cast().ToArray(), StringComparer.OrdinalIgnoreCase); - var responseHeadersDictionary = responseHeaders.ToDictionary(x => x.Key, x => x.Value.Cast().ToArray(), StringComparer.OrdinalIgnoreCase); + var contentHeadersDictionary = contentHeaders.ToDictionary(x => x.Key, x => x.Value.ToArray(), StringComparer.OrdinalIgnoreCase); + var responseHeadersDictionary = responseHeaders.ToDictionary(x => x.Key, x => x.Value.ToArray(), StringComparer.OrdinalIgnoreCase); var headersDictionary = contentHeadersDictionary.Concat(responseHeadersDictionary).ToDictionary(x => x.Key, x => x.Value, StringComparer.OrdinalIgnoreCase); return await context.ParseContentAsync(contentStream, contentType, targetType, headersDictionary, cancellationToken); } diff --git a/src/modules/Elsa.Http/Activities/WriteHttpResponse.cs b/src/modules/Elsa.Http/Activities/WriteHttpResponse.cs index 7b21e3353..2691cced5 100644 --- a/src/modules/Elsa.Http/Activities/WriteHttpResponse.cs +++ b/src/modules/Elsa.Http/Activities/WriteHttpResponse.cs @@ -101,7 +101,7 @@ public class WriteHttpResponse : Activity // Add headers. var headers = context.GetHeaders(ResponseHeaders); foreach (var header in headers) - response.Headers.Add(header.Key, header.Value); + response.Headers[header.Key] = header.Value; // Get content and content type. var content = context.Get(Content); diff --git a/src/modules/Elsa.Http/ContentWriters/FormUrlEncodedHttpContentFactory.cs b/src/modules/Elsa.Http/ContentWriters/FormUrlEncodedHttpContentFactory.cs index 5536181ea..ae4fc8539 100644 --- a/src/modules/Elsa.Http/ContentWriters/FormUrlEncodedHttpContentFactory.cs +++ b/src/modules/Elsa.Http/ContentWriters/FormUrlEncodedHttpContentFactory.cs @@ -20,7 +20,7 @@ public class FormUrlEncodedHttpContentFactory : IHttpContentFactory return dictionary.ToDictionary(x => x.Key, x => x.Value.ToString() ?? string.Empty); if (content is string or JsonObject) - return JsonSerializer.Deserialize>(JsonSerializer.Serialize(content)); + return JsonSerializer.Deserialize>(JsonSerializer.Serialize(content))!; var jsonElement = JsonSerializer.SerializeToElement(content); return jsonElement.EnumerateObject().ToDictionary(x => x.Name, x => x.Value.ToString()); diff --git a/src/modules/Elsa.Http/Extensions/HttpActivityExecutionContextExtensions.cs b/src/modules/Elsa.Http/Extensions/HttpActivityExecutionContextExtensions.cs index 3538ace13..85d45ff5e 100644 --- a/src/modules/Elsa.Http/Extensions/HttpActivityExecutionContextExtensions.cs +++ b/src/modules/Elsa.Http/Extensions/HttpActivityExecutionContextExtensions.cs @@ -8,7 +8,7 @@ namespace Elsa.Extensions; internal static class HttpActivityExecutionContextExtensions { - public static async Task ParseContentAsync(this ActivityExecutionContext context, Stream content, string contentType, Type? returnType, Dictionary headers, CancellationToken cancellationToken) + public static async Task ParseContentAsync(this ActivityExecutionContext context, Stream content, string contentType, Type? returnType, Dictionary headers, CancellationToken cancellationToken) { var parsers = context.GetServices().OrderByDescending(x => x.Priority).ToList(); var httpResponseParserContext = new HttpResponseParserContext(content, contentType, returnType, headers, cancellationToken); diff --git a/src/modules/Elsa.Http/Handlers/UpdateRouteTable.cs b/src/modules/Elsa.Http/Handlers/UpdateRouteTable.cs index 4d3571006..0ade01163 100644 --- a/src/modules/Elsa.Http/Handlers/UpdateRouteTable.cs +++ b/src/modules/Elsa.Http/Handlers/UpdateRouteTable.cs @@ -1,8 +1,6 @@ -using Elsa.Http.Options; -using Elsa.Mediator.Contracts; +using Elsa.Mediator.Contracts; using Elsa.Workflows.Runtime.Notifications; using JetBrains.Annotations; -using Microsoft.Extensions.Options; namespace Elsa.Http.Handlers; @@ -10,7 +8,7 @@ namespace Elsa.Http.Handlers; /// A handler that updates the route table when workflow triggers and bookmarks are indexed. /// [UsedImplicitly] -public class UpdateRouteTable(IRouteTableUpdater routeTableUpdater, IOptions options) : +public class UpdateRouteTable(IRouteTableUpdater routeTableUpdater) : INotificationHandler, INotificationHandler { diff --git a/src/modules/Elsa.Persistence.EFCore.Common/Extensions/BulkUpsertExtensions.cs b/src/modules/Elsa.Persistence.EFCore.Common/Extensions/BulkUpsertExtensions.cs index 9f24898ea..fadf509a7 100644 --- a/src/modules/Elsa.Persistence.EFCore.Common/Extensions/BulkUpsertExtensions.cs +++ b/src/modules/Elsa.Persistence.EFCore.Common/Extensions/BulkUpsertExtensions.cs @@ -113,7 +113,7 @@ public static class BulkUpsertExtensions var paramName = $"{{{parameterCount++}}}"; // If it's a shadow property, retrieve value via Entry(..).Property(..) - object? value = property.IsShadowProperty() + var value = property.IsShadowProperty() ? dbContext.Entry(entity).Property(property.Name).CurrentValue : property.PropertyInfo?.GetValue(entity); @@ -176,7 +176,7 @@ public static class BulkUpsertExtensions { var paramName = $"{{{parameterCount++}}}"; - object? value = property.IsShadowProperty() + var value = property.IsShadowProperty() ? dbContext.Entry(entity).Property(property.Name).CurrentValue : property.PropertyInfo?.GetValue(entity); @@ -185,7 +185,7 @@ public static class BulkUpsertExtensions value = converter.ConvertToProvider(value); placeholders.Add(paramName); - parameters.Add(value); + parameters.Add(value!); } sb.Append($"({string.Join(", ", placeholders)})"); @@ -238,7 +238,7 @@ public static class BulkUpsertExtensions { var paramName = $"{{{parameterCount++}}}"; - object? value = property.IsShadowProperty() + var value = property.IsShadowProperty() ? dbContext.Entry(entity).Property(property.Name).CurrentValue : property.PropertyInfo?.GetValue(entity); @@ -255,7 +255,7 @@ public static class BulkUpsertExtensions else placeholders.Add(paramName); - parameters.Add(value); + parameters.Add(value!); } sb.Append($"({string.Join(", ", placeholders)})"); @@ -308,7 +308,7 @@ public static class BulkUpsertExtensions { var paramName = $"{{{parameterCount++}}}"; - object? value = property.IsShadowProperty() + var value = property.IsShadowProperty() ? dbContext.Entry(entity).Property(property.Name).CurrentValue : property.PropertyInfo?.GetValue(entity); @@ -317,7 +317,7 @@ public static class BulkUpsertExtensions value = converter.ConvertToProvider(value); placeholders.Add(paramName); - parameters.Add(value); + parameters.Add(value!); } sb.Append($"({string.Join(", ", placeholders)})"); @@ -374,7 +374,7 @@ public static class BulkUpsertExtensions { var paramName = $"{{{parameterCount++}}}"; - object? value = property.IsShadowProperty() + var value = property.IsShadowProperty() ? dbContext.Entry(entity).Property(property.Name).CurrentValue : property.PropertyInfo?.GetValue(entity); @@ -382,7 +382,7 @@ public static class BulkUpsertExtensions if (converter != null) value = converter.ConvertToProvider(value); - parameters.Add(value); + parameters.Add(value!); // Oracle aliases must match the column name var alias = property.GetColumnName(storeObject); diff --git a/src/modules/Elsa.Persistence.EFCore.Common/JsonValueComparer.cs b/src/modules/Elsa.Persistence.EFCore.Common/JsonValueComparer.cs index 04fd79a67..db9d92238 100644 --- a/src/modules/Elsa.Persistence.EFCore.Common/JsonValueComparer.cs +++ b/src/modules/Elsa.Persistence.EFCore.Common/JsonValueComparer.cs @@ -13,7 +13,10 @@ namespace Elsa.Persistence.EFCore; /// For plain objects, fall back to deep equality comparison using JSON serialization /// (safe, but inefficient). /// -public class JsonValueComparer : ValueComparer { +public class JsonValueComparer() : ValueComparer((t1, t2) => DoEquals(t1!, t2!), + t => DoGetHashCode(t), + t => DoGetSnapshot(t)) +{ private static string Json(T instance) { return JsonSerializer.Serialize(instance); @@ -24,9 +27,7 @@ public class JsonValueComparer : ValueComparer { if (instance is ICloneable cloneable) return (T)cloneable.Clone(); - var result = (T)JsonSerializer.Deserialize(Json(instance)); - return result; - + return JsonSerializer.Deserialize(Json(instance))!; } private static int DoGetHashCode(T instance) { @@ -43,15 +44,6 @@ public class JsonValueComparer : ValueComparer { if (left is IEquatable equatable) return equatable.Equals(right); - var result = Json(left).Equals(Json(right)); - return result; - + return Json(left).Equals(Json(right)); } - - public JsonValueComparer() : base( - (t1, t2) => DoEquals(t1, t2), - t => DoGetHashCode(t), - t => DoGetSnapshot(t)) { - } - } \ No newline at end of file diff --git a/src/modules/Elsa.Persistence.EFCore.Common/JsonValueConverterHelper.cs b/src/modules/Elsa.Persistence.EFCore.Common/JsonValueConverterHelper.cs index d529731bf..6df4e4608 100644 --- a/src/modules/Elsa.Persistence.EFCore.Common/JsonValueConverterHelper.cs +++ b/src/modules/Elsa.Persistence.EFCore.Common/JsonValueConverterHelper.cs @@ -15,7 +15,7 @@ internal static class JsonValueConverterHelper public static string Serialize(T obj) where T : class { - return (obj == null ? null : JsonSerializer.Serialize(obj, JsonSerializerOptions))!; + return (obj == null! ? null : JsonSerializer.Serialize(obj, JsonSerializerOptions))!; } private static JsonSerializerOptions CreateJsonSerializerOptions() diff --git a/src/modules/Elsa.Persistence.EFCore/Modules/Management/WorkflowDefinitionStore.cs b/src/modules/Elsa.Persistence.EFCore/Modules/Management/WorkflowDefinitionStore.cs index 203348715..7c2ffc896 100644 --- a/src/modules/Elsa.Persistence.EFCore/Modules/Management/WorkflowDefinitionStore.cs +++ b/src/modules/Elsa.Persistence.EFCore/Modules/Management/WorkflowDefinitionStore.cs @@ -221,7 +221,7 @@ public class EFCoreWorkflowDefinitionStore(EntityStore x.IsSystem == true) - : queryable.Where(x => x.IsSystem == false || x.IsSystem == null); + : queryable.Where(x => x.IsSystem == false || x.IsSystem == null!); if (filter.IsReadonly != null) queryable = queryable.Where(x => x.IsReadonly == filter.IsReadonly); return queryable; diff --git a/src/modules/Elsa.Persistence.EFCore/Modules/Runtime/ActivityExecutionLogStore.cs b/src/modules/Elsa.Persistence.EFCore/Modules/Runtime/ActivityExecutionLogStore.cs index f10ded7fd..c345550c0 100644 --- a/src/modules/Elsa.Persistence.EFCore/Modules/Runtime/ActivityExecutionLogStore.cs +++ b/src/modules/Elsa.Persistence.EFCore/Modules/Runtime/ActivityExecutionLogStore.cs @@ -6,7 +6,6 @@ using Elsa.Common.Codecs; using Elsa.Common.Entities; using Elsa.Extensions; using Elsa.Workflows; -using Elsa.Workflows.Management.Options; using Elsa.Workflows.Runtime; using Elsa.Workflows.Runtime.Entities; using Elsa.Workflows.Runtime.Extensions; @@ -15,7 +14,6 @@ using Elsa.Workflows.Runtime.OrderDefinitions; using Elsa.Workflows.State; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Options; using Open.Linq.AsyncExtensions; namespace Elsa.Persistence.EFCore.Modules.Runtime; @@ -26,10 +24,8 @@ namespace Elsa.Persistence.EFCore.Modules.Runtime; [UsedImplicitly] public class EFCoreActivityExecutionStore( EntityStore store, - ISafeSerializer safeSerializer, IPayloadSerializer payloadSerializer, - ICompressionCodecResolver compressionCodecResolver, - IOptions options) : IActivityExecutionStore + ICompressionCodecResolver compressionCodecResolver) : IActivityExecutionStore { /// public async Task SaveAsync(ActivityExecutionRecord record, CancellationToken cancellationToken = default) => await store.SaveAsync(record, OnSaveAsync, cancellationToken); diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Export/Endpoint.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Export/Endpoint.cs index 4f876a7ce..364696e9c 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Export/Endpoint.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Export/Endpoint.cs @@ -48,13 +48,14 @@ internal class Export : ElsaEndpoint { if (request.DefinitionId != null) await DownloadSingleWorkflowAsync(request.DefinitionId, request.VersionOptions, cancellationToken); - else + else if (request.Ids != null) await DownloadMultipleWorkflowsAsync(request.Ids, cancellationToken); + else await Send.NoContentAsync(cancellationToken); } private async Task DownloadMultipleWorkflowsAsync(ICollection ids, CancellationToken cancellationToken) { - List definitions = (await _store.FindManyAsync(new WorkflowDefinitionFilter + List definitions = (await _store.FindManyAsync(new() { Ids = ids }, cancellationToken)).ToList(); @@ -88,7 +89,7 @@ internal class Export : ElsaEndpoint private async Task DownloadSingleWorkflowAsync(string definitionId, string? versionOptions, CancellationToken cancellationToken) { var parsedVersionOptions = string.IsNullOrEmpty(versionOptions) ? VersionOptions.Latest : VersionOptions.FromString(versionOptions); - WorkflowDefinition? definition = (await _store.FindManyAsync(new WorkflowDefinitionFilter + WorkflowDefinition? definition = (await _store.FindManyAsync(new() { DefinitionId = definitionId, VersionOptions = parsedVersionOptions diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/List/Endpoint.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/List/Endpoint.cs index 718c0ca99..c8ad5401b 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/List/Endpoint.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/List/Endpoint.cs @@ -151,7 +151,7 @@ internal class List(IWorkflowInstanceStore store) : ElsaEndpoint { - KeySelector = p => p.Name, + KeySelector = p => p.Name!, Direction = direction }; diff --git a/src/modules/Elsa.Workflows.Api/Requirements/NotReadOnlyRequirement.cs b/src/modules/Elsa.Workflows.Api/Requirements/NotReadOnlyRequirement.cs index 594896485..f11b00195 100644 --- a/src/modules/Elsa.Workflows.Api/Requirements/NotReadOnlyRequirement.cs +++ b/src/modules/Elsa.Workflows.Api/Requirements/NotReadOnlyRequirement.cs @@ -26,18 +26,19 @@ public class NotReadOnlyRequirementHandler : AuthorizationHandler - protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, NotReadOnlyRequirement requirement, NotReadOnlyResource resource) + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, NotReadOnlyRequirement requirement, NotReadOnlyResource resource) { if (_managementOptions.Value.IsReadOnlyMode) { - context.Fail(new AuthorizationFailureReason(this, "Workflow edit is not allowed when the read-only mode is enabled.")); + context.Fail(new(this, "Workflow edit is not allowed when the read-only mode is enabled.")); } if (resource.WorkflowDefinition != null && (resource.WorkflowDefinition.IsReadonly || resource.WorkflowDefinition.IsSystem)) { - context.Fail(new AuthorizationFailureReason(this, "Workflow edit is not allowed for a readonly or system workflow.")); + context.Fail(new(this, "Workflow edit is not allowed for a readonly or system workflow.")); } context.Succeed(requirement); + return Task.CompletedTask; } } \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Api/Serialization/ArgumentJsonConverter.cs b/src/modules/Elsa.Workflows.Api/Serialization/ArgumentJsonConverter.cs index febe80558..303b38aac 100644 --- a/src/modules/Elsa.Workflows.Api/Serialization/ArgumentJsonConverter.cs +++ b/src/modules/Elsa.Workflows.Api/Serialization/ArgumentJsonConverter.cs @@ -33,7 +33,7 @@ public class ArgumentJsonConverter : JsonConverter var typeAlias = _wellKnownTypeRegistry.TryGetAlias(typeName, out var alias) ? alias : null; var isArray = typeName.IsArray; var isCollection = typeName.IsCollectionType(); - var elementTypeName = isArray ? typeName.GetElementType() : isCollection ? typeName.GenericTypeArguments[0] : typeName; + var elementTypeName = isArray ? typeName.GetElementType()! : isCollection ? typeName.GenericTypeArguments[0] : typeName; var elementTypeAlias = _wellKnownTypeRegistry.GetAliasOrDefault(elementTypeName); var isAliasedArray = (isArray || isCollection) && typeAlias != null; var finalTypeAlias = isArray || isCollection ? typeAlias ?? elementTypeAlias : elementTypeAlias; diff --git a/src/modules/Elsa.Workflows.Core/Activities/ParallelForEachT.cs b/src/modules/Elsa.Workflows.Core/Activities/ParallelForEachT.cs index 274141172..9aa4c311c 100644 --- a/src/modules/Elsa.Workflows.Core/Activities/ParallelForEachT.cs +++ b/src/modules/Elsa.Workflows.Core/Activities/ParallelForEachT.cs @@ -90,7 +90,7 @@ public class ParallelForEach : Activity private ICollection GetTagList(ActivityExecutionContext context, string propertyName) { // Read the list of tags from the context using the specified property name. The value is stored as JsonArray, so we need to deserialize it. - var jsonArray = context.GetProperty(propertyName); + var jsonArray = context.GetProperty(propertyName)!; return jsonArray.Select(x => x.ConvertTo()).ToList(); } diff --git a/src/modules/Elsa.Workflows.Core/Builders/WorkflowBuilder.cs b/src/modules/Elsa.Workflows.Core/Builders/WorkflowBuilder.cs index b30d7669e..fd5608325 100644 --- a/src/modules/Elsa.Workflows.Core/Builders/WorkflowBuilder.cs +++ b/src/modules/Elsa.Workflows.Core/Builders/WorkflowBuilder.cs @@ -6,7 +6,7 @@ using Elsa.Workflows.Models; namespace Elsa.Workflows.Builders; /// -public class WorkflowBuilder(IActivityVisitor activityVisitor, IIdentityGraphService identityGraphService, IActivityRegistry activityRegistry, IIdentityGenerator identityGenerator) +public class WorkflowBuilder(IActivityVisitor activityVisitor, IIdentityGraphService identityGraphService, IActivityRegistry activityRegistry) : IWorkflowBuilder { /// diff --git a/src/modules/Elsa.Workflows.Core/Contexts/WorkflowExecutionContext.cs b/src/modules/Elsa.Workflows.Core/Contexts/WorkflowExecutionContext.cs index fa1f67c30..33906c603 100644 --- a/src/modules/Elsa.Workflows.Core/Contexts/WorkflowExecutionContext.cs +++ b/src/modules/Elsa.Workflows.Core/Contexts/WorkflowExecutionContext.cs @@ -402,7 +402,7 @@ public partial class WorkflowExecutionContext : IExecutionContext /// /// The expression execution context for the current workflow execution. /// - public ExpressionExecutionContext? ExpressionExecutionContext { get; private set; } + public ExpressionExecutionContext ExpressionExecutionContext { get; private set; } = null!; /// public IEnumerable Variables => Workflow.Variables; diff --git a/src/modules/Elsa.Workflows.Core/Middleware/Activities/ExceptionHandlingMiddleware.cs b/src/modules/Elsa.Workflows.Core/Middleware/Activities/ExceptionHandlingMiddleware.cs index b7028e2b8..e2237498c 100644 --- a/src/modules/Elsa.Workflows.Core/Middleware/Activities/ExceptionHandlingMiddleware.cs +++ b/src/modules/Elsa.Workflows.Core/Middleware/Activities/ExceptionHandlingMiddleware.cs @@ -1,4 +1,3 @@ -using Elsa.Common; using Elsa.Extensions; using Elsa.Workflows.Pipelines.ActivityExecution; using Microsoft.Extensions.Logging; @@ -19,7 +18,7 @@ public static class ExceptionHandlingMiddlewareExtensions /// /// Catches any exceptions thrown by downstream components and transitions the workflow into the faulted state. /// -public class ExceptionHandlingMiddleware(ActivityMiddlewareDelegate next, IIncidentStrategyResolver incidentStrategyResolver, ISystemClock systemClock, ILogger logger) +public class ExceptionHandlingMiddleware(ActivityMiddlewareDelegate next, IIncidentStrategyResolver incidentStrategyResolver, ILogger logger) : IActivityExecutionMiddleware { /// diff --git a/src/modules/Elsa.Workflows.Core/Serialization/Converters/PolymorphicObjectConverter.cs b/src/modules/Elsa.Workflows.Core/Serialization/Converters/PolymorphicObjectConverter.cs index 00c49da52..838dae398 100644 --- a/src/modules/Elsa.Workflows.Core/Serialization/Converters/PolymorphicObjectConverter.cs +++ b/src/modules/Elsa.Workflows.Core/Serialization/Converters/PolymorphicObjectConverter.cs @@ -4,7 +4,6 @@ using System.Reflection; using System.Text.Json; using System.Text.Json.Nodes; using System.Text.Json.Serialization; -using Elsa.Expressions.Contracts; using Elsa.Extensions; using Elsa.Workflows.Serialization.ReferenceHandlers; using Newtonsoft.Json.Linq; @@ -14,7 +13,7 @@ namespace Elsa.Workflows.Serialization.Converters; /// /// Reads objects as primitive types rather than values while also maintaining the .NET type name for reconstructing the actual type. /// -public class PolymorphicObjectConverter(IWellKnownTypeRegistry wellKnownTypeRegistry) : JsonConverter +public class PolymorphicObjectConverter : JsonConverter { private const string TypePropertyName = "_type"; private const string ItemsPropertyName = "_items"; @@ -77,7 +76,7 @@ public class PolymorphicObjectConverter(IWellKnownTypeRegistry wellKnownTypeRegi { var parsedModel = JsonElement.ParseValue(ref reader); var systemTextJson = parsedModel.GetProperty(IslandPropertyName).GetString(); - return !string.IsNullOrWhiteSpace(systemTextJson) ? JsonObject.Parse(systemTextJson) : new JsonObject(); + return !string.IsNullOrWhiteSpace(systemTextJson) ? JsonNode.Parse(systemTextJson)! : new JsonObject(); } var isJsonArray = targetType == typeof(JsonArray); @@ -86,7 +85,7 @@ public class PolymorphicObjectConverter(IWellKnownTypeRegistry wellKnownTypeRegi { var parsedModel = JsonElement.ParseValue(ref reader); var systemTextJson = parsedModel.GetProperty(IslandPropertyName).GetString(); - return !string.IsNullOrWhiteSpace(systemTextJson) ? JsonArray.Parse(systemTextJson) : new JsonArray(); + return !string.IsNullOrWhiteSpace(systemTextJson) ? JsonNode.Parse(systemTextJson)! : new JsonArray(); } var isDictionary = typeof(IDictionary).IsAssignableFrom(targetType); diff --git a/src/modules/Elsa.Workflows.Core/Serialization/Converters/PolymorphicObjectConverterFactory.cs b/src/modules/Elsa.Workflows.Core/Serialization/Converters/PolymorphicObjectConverterFactory.cs index 4a8cdcb7e..2317a6372 100644 --- a/src/modules/Elsa.Workflows.Core/Serialization/Converters/PolymorphicObjectConverterFactory.cs +++ b/src/modules/Elsa.Workflows.Core/Serialization/Converters/PolymorphicObjectConverterFactory.cs @@ -51,6 +51,6 @@ public class PolymorphicObjectConverterFactory : JsonConverterFactory if (typeof(IDictionary).IsAssignableFrom(typeToConvert)) return new PolymorphicDictionaryConverter(options, _wellKnownTypeRegistry); - return new PolymorphicObjectConverter(_wellKnownTypeRegistry); + return new PolymorphicObjectConverter(); } } \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Core/VariableStorageDrivers/WorkflowInstanceStorageDriver.cs b/src/modules/Elsa.Workflows.Core/VariableStorageDrivers/WorkflowInstanceStorageDriver.cs index bb93720e3..469969041 100644 --- a/src/modules/Elsa.Workflows.Core/VariableStorageDrivers/WorkflowInstanceStorageDriver.cs +++ b/src/modules/Elsa.Workflows.Core/VariableStorageDrivers/WorkflowInstanceStorageDriver.cs @@ -33,7 +33,7 @@ public class WorkflowInstanceStorageDriver(IPayloadSerializer payloadSerializer, try { var node = JsonSerializer.SerializeToNode(value); - dictionary[id] = node; + dictionary[id] = node!; } catch (Exception ex) when (ex is JsonException or NotSupportedException or ObjectDisposedException) { diff --git a/src/modules/Elsa.Workflows.Management/Activities/WorkflowDefinitionActivity/WorkflowDefinitionActivity.cs b/src/modules/Elsa.Workflows.Management/Activities/WorkflowDefinitionActivity/WorkflowDefinitionActivity.cs index e5f69bb47..e618ad467 100644 --- a/src/modules/Elsa.Workflows.Management/Activities/WorkflowDefinitionActivity/WorkflowDefinitionActivity.cs +++ b/src/modules/Elsa.Workflows.Management/Activities/WorkflowDefinitionActivity/WorkflowDefinitionActivity.cs @@ -125,6 +125,13 @@ public class WorkflowDefinitionActivity : Composite, IInitializable var serviceProvider = context.GetRequiredService(); var activityDescriptor = await FindActivityDescriptorAsync(serviceProvider); + if (activityDescriptor == null) + { + var logger = serviceProvider.GetRequiredService>(); + logger.LogWarning("Could not find activity descriptor for activity type {ActivityType}", Type); + return; + } + DeclareInputAsVariables(activityDescriptor, (descriptor, variable) => { var inputName = descriptor.Name; diff --git a/src/modules/Elsa.Workflows.Management/Mappers/VariableDefinitionMapper.cs b/src/modules/Elsa.Workflows.Management/Mappers/VariableDefinitionMapper.cs index c1c3e491c..cd0bc53b7 100644 --- a/src/modules/Elsa.Workflows.Management/Mappers/VariableDefinitionMapper.cs +++ b/src/modules/Elsa.Workflows.Management/Mappers/VariableDefinitionMapper.cs @@ -81,7 +81,7 @@ public class VariableDefinitionMapper(IWellKnownTypeRegistry wellKnownTypeRegist var isArray = valueType.IsArray; var isCollection = valueType.IsCollectionType(); - var elementValueType = isArray ? valueType.GetElementType() : isCollection ? valueType.GenericTypeArguments[0] : valueType; + var elementValueType = isArray ? valueType.GetElementType()! : isCollection ? valueType.GenericTypeArguments[0] : valueType; var elementTypeAlias = wellKnownTypeRegistry.GetAliasOrDefault(elementValueType); return new(source.Id, source.Name, elementTypeAlias, isArray, serializedValue, storageDriverTypeName); diff --git a/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowDispatcher.cs b/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowDispatcher.cs index 0a99360f1..19aca5c02 100644 --- a/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowDispatcher.cs +++ b/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowDispatcher.cs @@ -11,20 +11,20 @@ public interface IWorkflowDispatcher /// /// Dispatches a request to execute the specified workflow definition. /// - Task DispatchAsync(DispatchWorkflowDefinitionRequest request, DispatchWorkflowOptions options, CancellationToken cancellationToken = default); + Task DispatchAsync(DispatchWorkflowDefinitionRequest request, DispatchWorkflowOptions? options, CancellationToken cancellationToken = default); /// /// Dispatches a request to execute the specified workflow instance. /// - Task DispatchAsync(DispatchWorkflowInstanceRequest request, DispatchWorkflowOptions options, CancellationToken cancellationToken = default); + Task DispatchAsync(DispatchWorkflowInstanceRequest request, DispatchWorkflowOptions? options, CancellationToken cancellationToken = default); /// /// Starts all workflows and resumes existing workflow instances based on the specified activity type and bookmark payload. /// - Task DispatchAsync(DispatchTriggerWorkflowsRequest request, DispatchWorkflowOptions options, CancellationToken cancellationToken = default); + Task DispatchAsync(DispatchTriggerWorkflowsRequest request, DispatchWorkflowOptions? options, CancellationToken cancellationToken = default); /// /// Resumes the workflow waiting for the specified bookmark. /// - Task DispatchAsync(DispatchResumeWorkflowsRequest request, DispatchWorkflowOptions options, CancellationToken cancellationToken = default); + Task DispatchAsync(DispatchResumeWorkflowsRequest request, DispatchWorkflowOptions? options, CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowExecutionLogStore.cs b/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowExecutionLogStore.cs index 08bbe25cc..50a4767a0 100644 --- a/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowExecutionLogStore.cs +++ b/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowExecutionLogStore.cs @@ -15,11 +15,6 @@ public interface IWorkflowExecutionLogStore : ILogRecordStore Task AddAsync(WorkflowExecutionLogRecord record, CancellationToken cancellationToken = default); - /// - /// Adds the specified set of objects to te persistence store. - /// - Task AddManyAsync(IEnumerable records, CancellationToken cancellationToken = default); - /// /// Adds or updates the specified in the persistence store. /// diff --git a/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs b/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs index e5ab1d60f..501a67276 100644 --- a/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs +++ b/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs @@ -17,7 +17,6 @@ using Elsa.Workflows.Runtime.Entities; using Elsa.Workflows.Runtime.Handlers; using Elsa.Workflows.Runtime.Options; using Elsa.Workflows.Runtime.Providers; -using Elsa.Workflows.Runtime.Services; using Elsa.Workflows.Runtime.Stores; using Elsa.Workflows.Runtime.Tasks; using Elsa.Workflows.Runtime.UIHints; diff --git a/src/modules/Elsa.Workflows.Runtime/Filters/TriggerFilter.cs b/src/modules/Elsa.Workflows.Runtime/Filters/TriggerFilter.cs index cab0d7536..8435349aa 100644 --- a/src/modules/Elsa.Workflows.Runtime/Filters/TriggerFilter.cs +++ b/src/modules/Elsa.Workflows.Runtime/Filters/TriggerFilter.cs @@ -69,7 +69,7 @@ public class TriggerFilter if (WorkflowDefinitionVersionId != null) queryable = queryable.Where(x => x.WorkflowDefinitionVersionId == WorkflowDefinitionVersionId); if (WorkflowDefinitionVersionIds != null) queryable = queryable.Where(x => WorkflowDefinitionVersionIds.Contains(x.WorkflowDefinitionVersionId)); if (Name != null) queryable = queryable.Where(x => x.Name == Name); - if (Names != null) queryable = queryable.Where(x => Names.Contains(x.Name)); + if (Names != null) queryable = queryable.Where(x => Names.Contains(x.Name!)); if (Hash != null) queryable = queryable.Where(x => x.Hash == Hash); return queryable; } diff --git a/src/modules/Elsa.Workflows.Runtime/Handlers/ResumeDispatchWorkflowActivity.cs b/src/modules/Elsa.Workflows.Runtime/Handlers/ResumeDispatchWorkflowActivity.cs index 37b95583a..0b5046134 100644 --- a/src/modules/Elsa.Workflows.Runtime/Handlers/ResumeDispatchWorkflowActivity.cs +++ b/src/modules/Elsa.Workflows.Runtime/Handlers/ResumeDispatchWorkflowActivity.cs @@ -4,7 +4,6 @@ using Elsa.Workflows.Notifications; using Elsa.Workflows.Runtime.Activities; using Elsa.Workflows.Runtime.Stimuli; using JetBrains.Annotations; -using Microsoft.Extensions.Logging; namespace Elsa.Workflows.Runtime.Handlers; @@ -12,7 +11,7 @@ namespace Elsa.Workflows.Runtime.Handlers; /// Resumes any blocking activities when its child workflow completes. /// [PublicAPI] -internal class ResumeDispatchWorkflowActivity(IBookmarkQueue bookmarkQueue, IStimulusHasher stimulusHasher, ILogger logger) : INotificationHandler +internal class ResumeDispatchWorkflowActivity(IBookmarkQueue bookmarkQueue, IStimulusHasher stimulusHasher) : INotificationHandler { private static readonly string ActivityTypeName = ActivityTypeNameHelper.GenerateTypeName(); diff --git a/src/modules/Elsa.Workflows.Runtime/Services/ObsoleteWorkflowRuntime.cs b/src/modules/Elsa.Workflows.Runtime/Services/ObsoleteWorkflowRuntime.cs index f836f98a7..f317b7403 100644 --- a/src/modules/Elsa.Workflows.Runtime/Services/ObsoleteWorkflowRuntime.cs +++ b/src/modules/Elsa.Workflows.Runtime/Services/ObsoleteWorkflowRuntime.cs @@ -67,7 +67,7 @@ public class ObsoleteWorkflowRuntime( TriggerActivityId = options?.TriggerActivityId }; var response = await client.CreateAndRunInstanceAsync(createRequest, cancellationToken); - return new(response.WorkflowInstanceId, response.Status, response.SubStatus, response.Bookmarks, response.Incidents, null, null); + return new(response.WorkflowInstanceId, response.Status, response.SubStatus, response.Bookmarks, response.Incidents, null, new Dictionary()); } public async Task> StartWorkflowsAsync(string activityTypeName, object bookmarkPayload, TriggerWorkflowsOptions? options = null) @@ -82,7 +82,7 @@ public class ObsoleteWorkflowRuntime( Input = options?.Input }; var result = await stimulusSender.SendAsync(activityTypeName, bookmarkPayload, metadata, cancellationToken); - var results = result.WorkflowInstanceResponses.Select(x => new WorkflowExecutionResult(x.WorkflowInstanceId, x.Status, x.SubStatus, x.Bookmarks, x.Incidents, null, null)).ToList(); + var results = result.WorkflowInstanceResponses.Select(x => new WorkflowExecutionResult(x.WorkflowInstanceId, x.Status, x.SubStatus, x.Bookmarks, x.Incidents, null, new Dictionary())).ToList(); return results; } @@ -110,7 +110,7 @@ public class ObsoleteWorkflowRuntime( var response = await workflowClient.RunInstanceAsync(runWorkflowRequest, cancellationToken); - return new(response.WorkflowInstanceId, response.Status, response.SubStatus, response.Bookmarks, response.Incidents,null, null); + return new(response.WorkflowInstanceId, response.Status, response.SubStatus, response.Bookmarks, response.Incidents,null, new Dictionary()); } public async Task> ResumeWorkflowsAsync(string activityTypeName, object bookmarkPayload, TriggerWorkflowsOptions? options = null) @@ -125,7 +125,7 @@ public class ObsoleteWorkflowRuntime( Input = options?.Input }; var result = await stimulusSender.SendAsync(activityTypeName, bookmarkPayload, metadata, cancellationToken); - var results = result.WorkflowInstanceResponses.Select(x => new WorkflowExecutionResult(x.WorkflowInstanceId, x.Status, x.SubStatus, x.Bookmarks, x.Incidents, null, null)).ToList(); + var results = result.WorkflowInstanceResponses.Select(x => new WorkflowExecutionResult(x.WorkflowInstanceId, x.Status, x.SubStatus, x.Bookmarks, x.Incidents, null, new Dictionary())).ToList(); return results; } @@ -141,7 +141,7 @@ public class ObsoleteWorkflowRuntime( Input = options?.Input }; var result = await stimulusSender.SendAsync(activityTypeName, bookmarkPayload, metadata, cancellationToken); - var results = result.WorkflowInstanceResponses.Select(x => new WorkflowExecutionResult(x.WorkflowInstanceId, x.Status, x.SubStatus, x.Bookmarks, x.Incidents, null, null)).ToList(); + var results = result.WorkflowInstanceResponses.Select(x => new WorkflowExecutionResult(x.WorkflowInstanceId, x.Status, x.SubStatus, x.Bookmarks, x.Incidents, null, new Dictionary())).ToList(); return new(results); } diff --git a/src/modules/Elsa.Workflows.Runtime/Services/StimulusProxyWorkflowInbox.cs b/src/modules/Elsa.Workflows.Runtime/Services/StimulusProxyWorkflowInbox.cs index 9a16af564..3a5d233aa 100644 --- a/src/modules/Elsa.Workflows.Runtime/Services/StimulusProxyWorkflowInbox.cs +++ b/src/modules/Elsa.Workflows.Runtime/Services/StimulusProxyWorkflowInbox.cs @@ -182,7 +182,7 @@ public class StimulusProxyWorkflowInbox( new List(), response.Incidents, null, - null) + new Dictionary()) ); } } \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Runtime/Services/StoreActivityExecutionLogSink.cs b/src/modules/Elsa.Workflows.Runtime/Services/StoreActivityExecutionLogSink.cs index 72325955b..b3abf9795 100644 --- a/src/modules/Elsa.Workflows.Runtime/Services/StoreActivityExecutionLogSink.cs +++ b/src/modules/Elsa.Workflows.Runtime/Services/StoreActivityExecutionLogSink.cs @@ -3,14 +3,13 @@ using Elsa.Mediator.Contracts; using Elsa.Workflows.Runtime.Entities; using Elsa.Workflows.Runtime.Notifications; -namespace Elsa.Workflows.Runtime.Services; +namespace Elsa.Workflows.Runtime; /// /// This implementation saves directly through the store. /// public class StoreActivityExecutionLogSink( IActivityExecutionStore activityExecutionStore, - IActivityExecutionMapper mapper, INotificationSender notificationSender) : ILogRecordSink { diff --git a/src/modules/Elsa.Workflows.Runtime/Services/ValidatingWorkflowDispatcher.cs b/src/modules/Elsa.Workflows.Runtime/Services/ValidatingWorkflowDispatcher.cs index 1126c3031..41361af8b 100644 --- a/src/modules/Elsa.Workflows.Runtime/Services/ValidatingWorkflowDispatcher.cs +++ b/src/modules/Elsa.Workflows.Runtime/Services/ValidatingWorkflowDispatcher.cs @@ -15,7 +15,7 @@ public class ValidatingWorkflowDispatcher(IWorkflowDispatcher decoratedService, private IWorkflowDispatcher DecoratedService { get; set; } = decoratedService; /// - public async Task DispatchAsync(DispatchWorkflowDefinitionRequest request, DispatchWorkflowOptions? options = default, CancellationToken cancellationToken = default) + public async Task DispatchAsync(DispatchWorkflowDefinitionRequest request, DispatchWorkflowOptions? options = null, CancellationToken cancellationToken = default) { if (!ValidateChannel(options?.Channel)) return DispatchWorkflowResponse.UnknownChannel(); @@ -24,7 +24,7 @@ public class ValidatingWorkflowDispatcher(IWorkflowDispatcher decoratedService, } /// - public async Task DispatchAsync(DispatchWorkflowInstanceRequest request, DispatchWorkflowOptions? options = default, CancellationToken cancellationToken = default) + public async Task DispatchAsync(DispatchWorkflowInstanceRequest request, DispatchWorkflowOptions? options = null, CancellationToken cancellationToken = default) { if (!ValidateChannel(options?.Channel)) return DispatchWorkflowResponse.UnknownChannel(); @@ -33,7 +33,7 @@ public class ValidatingWorkflowDispatcher(IWorkflowDispatcher decoratedService, } /// - public async Task DispatchAsync(DispatchTriggerWorkflowsRequest request, DispatchWorkflowOptions? options = default, CancellationToken cancellationToken = default) + public async Task DispatchAsync(DispatchTriggerWorkflowsRequest request, DispatchWorkflowOptions? options = null, CancellationToken cancellationToken = default) { if (!ValidateChannel(options?.Channel)) return DispatchWorkflowResponse.UnknownChannel(); @@ -42,7 +42,7 @@ public class ValidatingWorkflowDispatcher(IWorkflowDispatcher decoratedService, } /// - public async Task DispatchAsync(DispatchResumeWorkflowsRequest request, DispatchWorkflowOptions? options = default, CancellationToken cancellationToken = default) + public async Task DispatchAsync(DispatchResumeWorkflowsRequest request, DispatchWorkflowOptions? options = null, CancellationToken cancellationToken = default) { if (!ValidateChannel(options?.Channel)) return DispatchWorkflowResponse.UnknownChannel(); diff --git a/test/component/Elsa.Workflows.ComponentTests/Helpers/Activities/TriggerSignal.cs b/test/component/Elsa.Workflows.ComponentTests/Helpers/Activities/TriggerSignal.cs index 66e936878..75efc701a 100644 --- a/test/component/Elsa.Workflows.ComponentTests/Helpers/Activities/TriggerSignal.cs +++ b/test/component/Elsa.Workflows.ComponentTests/Helpers/Activities/TriggerSignal.cs @@ -45,7 +45,7 @@ public class TriggerSignal : CodeActivity /// public TriggerSignal(Input eventName, [CallerFilePath] string? source = null, [CallerLineNumber] int? line = null) : this(source, line) => EventName = eventName; - public Input EventName { get; set; } + public Input EventName { get; set; } = null!; protected override void Execute(ActivityExecutionContext context) { diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/Activities/Composition/BulkDispatchWorkflows/BulkDispatchWorkflowsTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/Activities/Composition/BulkDispatchWorkflows/BulkDispatchWorkflowsTests.cs index 448fed7a8..34af7f849 100644 --- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/Activities/Composition/BulkDispatchWorkflows/BulkDispatchWorkflowsTests.cs +++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/Activities/Composition/BulkDispatchWorkflows/BulkDispatchWorkflowsTests.cs @@ -127,7 +127,7 @@ public class BulkDispatchWorkflowsTests : AppComponentTest Assert.Equal(WorkflowSubStatus.Finished, result.WorkflowExecutionContext.SubStatus); } - private async Task GetWorkflowVariableAsync(TestWorkflowExecutionResult result, string variableName) + private async Task GetWorkflowVariableAsync(TestWorkflowExecutionResult result, string variableName) { var variableManager = Scope.ServiceProvider.GetRequiredService(); var variables = await variableManager.GetVariablesAsync(result.WorkflowExecutionContext); diff --git a/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/FlowchartNextActivity/Tests.cs b/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/FlowchartNextActivity/Tests.cs index 7a0fe6d1c..dd25a4f73 100644 --- a/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/FlowchartNextActivity/Tests.cs +++ b/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/FlowchartNextActivity/Tests.cs @@ -188,7 +188,7 @@ public class FlowchartNextActivityTests var result = await _workflowRunner.RunAsync(workflow); var lines = _capturingTextWriter.Lines.ToList(); Assert.Equal(WorkflowSubStatus.Faulted, result.WorkflowState.SubStatus); - Assert.Equal(1, result.WorkflowState.Incidents.Count()); + Assert.Single(result.WorkflowState.Incidents); Assert.Equal("Invalid backward connection: Every path from the source ('WriteLineE') must go through the target ('WriteLineC') when tracing back to the start.", result.WorkflowState.Incidents.First().Message); Assert.Equal(new[] { diff --git a/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/Incidents/IncidentStrategyTests.cs b/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/Incidents/IncidentStrategyTests.cs index 9f82e7d03..ad8880b2c 100644 --- a/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/Incidents/IncidentStrategyTests.cs +++ b/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/Incidents/IncidentStrategyTests.cs @@ -30,6 +30,6 @@ public class IncidentStrategyTests var lines = _capturingTextWriter.Lines.ToList(); Assert.Equal(expectedOutput, lines); Assert.Equal(expectedSubStatus, workflowState.SubStatus); - Assert.Equal(1, workflowState.Incidents.Count); + Assert.Single(workflowState.Incidents); } } \ No newline at end of file diff --git a/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/Serialization/Tests.cs b/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/Serialization/Tests.cs index 786c7a8ba..9c44a3efe 100644 --- a/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/Serialization/Tests.cs +++ b/test/integration/Elsa.Workflows.IntegrationTests/Scenarios/Serialization/Tests.cs @@ -24,8 +24,8 @@ public class Tests public async Task Test1() { await _services.PopulateRegistriesAsync(); - var workflowDefinition = _publisher.New(); - var root = _serializer.Deserialize(workflowDefinition.StringData); + var workflowDefinition = await _publisher.NewAsync(); + var root = _serializer.Deserialize(workflowDefinition.StringData!); Assert.NotNull(root); } } \ No newline at end of file diff --git a/test/integration/Elsa.Workflows.IntegrationTests/Serialization/ContainerSerialization/Tests.cs b/test/integration/Elsa.Workflows.IntegrationTests/Serialization/ContainerSerialization/Tests.cs index e3f2c9716..ae7af0a84 100644 --- a/test/integration/Elsa.Workflows.IntegrationTests/Serialization/ContainerSerialization/Tests.cs +++ b/test/integration/Elsa.Workflows.IntegrationTests/Serialization/ContainerSerialization/Tests.cs @@ -79,8 +79,8 @@ public class Tests new(start, writeLine), new(writeLine, end), }, + RunAsynchronously = false }; - container.RunAsynchronously = false; // Act @@ -93,12 +93,11 @@ public class Tests } [Fact] - public async void SerializeSequenceContainerTest() + public async Task SerializeSequenceContainerTest() { await _services.PopulateRegistriesAsync(); // Arrange - var container = new Sequence { Id = "sequence", @@ -127,9 +126,9 @@ public class Tests { "int", 10 }, { "bool", false }, { "string", "str"}, - } + }, + RunAsynchronously = false }; - container.RunAsynchronously = false; // Act @@ -142,12 +141,11 @@ public class Tests } [Fact] - public async void SerializeParallelContainerTest() + public async Task SerializeParallelContainerTest() { await _services.PopulateRegistriesAsync(); // Arrange - var container = new Workflows.Activities.Parallel { Id = "parallel", @@ -177,9 +175,9 @@ public class Tests { "int", 10 }, { "bool", false }, { "string", "str"}, - } + }, + RunAsynchronously = false }; - container.RunAsynchronously = false; // Act @@ -199,10 +197,16 @@ public class Tests // Assert.Equivalent has trouble with the Behavior.Owner reference - since these aren't serialzied anyway, ignore them deserializedContainer.Behaviors.Clear(); container.Behaviors.Clear(); - foreach (Activity activity in deserializedContainer.Activities) + foreach (var activity1 in deserializedContainer.Activities) + { + var activity = (Activity)activity1; activity.Behaviors.Clear(); - foreach (Activity activity in container.Activities) + } + + foreach (var activity in container.Activities.Cast()) + { activity.Behaviors.Clear(); + } // strict:false here allows "actual" to have extra public members that aren't part of "expected", and collection // comparison allows "actual" to have more data in it than is present in "expected". diff --git a/test/integration/Elsa.Workflows.IntegrationTests/Serialization/JsonSerialization/Tests.cs b/test/integration/Elsa.Workflows.IntegrationTests/Serialization/JsonSerialization/Tests.cs index f4a853f28..e8e6343a9 100644 --- a/test/integration/Elsa.Workflows.IntegrationTests/Serialization/JsonSerialization/Tests.cs +++ b/test/integration/Elsa.Workflows.IntegrationTests/Serialization/JsonSerialization/Tests.cs @@ -158,7 +158,7 @@ public class SerializationTests(ITestOutputHelper testOutputHelper) "StatusCode", "Created" }, { - "Content", isArray ? (type == typeof(JArray) ? JArray.Parse(jsonContent) : JsonArray.Parse(jsonContent)) : (type == typeof(JObject) ? JObject.Parse(jsonContent) : JsonObject.Parse(jsonContent)) + "Content", (isArray ? type == typeof(JArray) ? JArray.Parse(jsonContent) : JsonNode.Parse(jsonContent) : type == typeof(JObject) ? JObject.Parse(jsonContent) : JsonNode.Parse(jsonContent))! } }; return dict; diff --git a/test/integration/Elsa.Workflows.IntegrationTests/Serialization/UIHintSerializiation/ActivityUIHintDescriberTests.cs b/test/integration/Elsa.Workflows.IntegrationTests/Serialization/UIHintSerializiation/ActivityUIHintDescriberTests.cs index 284d665c8..efcdc8e39 100644 --- a/test/integration/Elsa.Workflows.IntegrationTests/Serialization/UIHintSerializiation/ActivityUIHintDescriberTests.cs +++ b/test/integration/Elsa.Workflows.IntegrationTests/Serialization/UIHintSerializiation/ActivityUIHintDescriberTests.cs @@ -45,11 +45,11 @@ public class Tests var description = await activityDescriber.DescribeActivityAsync(typeof(TestActivity)); var inputDescription = description.Inputs.First(); - Assert.True(inputDescription.UISpecifications.ContainsKey(InputUIHints.DropDown)); + Assert.True(inputDescription.UISpecifications!.ContainsKey(InputUIHints.DropDown)); Assert.True(inputDescription.UISpecifications[InputUIHints.DropDown] is DropDownProps); var dropDownProperties = (DropDownProps) inputDescription.UISpecifications[InputUIHints.DropDown]; - Assert.Collection(dropDownProperties.SelectList.Items, + Assert.Collection(dropDownProperties.SelectList!.Items, item => { Assert.Equal("OptionsAreNice", item.Text); Assert.Equal("OptionsAreNice", item.Value); }, item => { Assert.Equal("ToHave", item.Text); Assert.Equal("ToHave", item.Value); }, item => { Assert.Equal("IfYouCanChooseThem", item.Text); Assert.Equal("IfYouCanChooseThem", item.Value); }); diff --git a/test/performance/Elsa.Workflows.PerformanceTests/ConsoleActivitiesBenchmark.cs b/test/performance/Elsa.Workflows.PerformanceTests/ConsoleActivitiesBenchmark.cs index 9f214cf1b..f8d6041fa 100644 --- a/test/performance/Elsa.Workflows.PerformanceTests/ConsoleActivitiesBenchmark.cs +++ b/test/performance/Elsa.Workflows.PerformanceTests/ConsoleActivitiesBenchmark.cs @@ -8,9 +8,9 @@ namespace Elsa.Workflows.PerformanceTests; [Config(typeof(Config))] public class ConsoleActivitiesBenchmark { - private WriteLine _writeLineWorkflow; - private IWorkflowRunner _workflowRunner; - private ServiceProvider _serviceProvider; + private WriteLine _writeLineWorkflow = null!; + private IWorkflowRunner _workflowRunner = null!; + private ServiceProvider _serviceProvider = null!; [GlobalSetup] public void GlobalSetup() @@ -21,7 +21,7 @@ public class ConsoleActivitiesBenchmark _serviceProvider = services.BuildServiceProvider(); _workflowRunner = _serviceProvider.GetRequiredService(); - _writeLineWorkflow = new WriteLine("Hello, World!"); + _writeLineWorkflow = new("Hello, World!"); } [Benchmark] diff --git a/test/unit/Elsa.Activities.UnitTests/Composition/ExecuteWorkflowTests.cs b/test/unit/Elsa.Activities.UnitTests/Composition/ExecuteWorkflowTests.cs index 1dd0a993c..c95c226a2 100644 --- a/test/unit/Elsa.Activities.UnitTests/Composition/ExecuteWorkflowTests.cs +++ b/test/unit/Elsa.Activities.UnitTests/Composition/ExecuteWorkflowTests.cs @@ -50,7 +50,7 @@ public class ExecuteWorkflowTests opts.CorrelationId == DefaultCorrelationId && opts.Input != null && opts.Input.ContainsKey("Key1") && (string)opts.Input["Key1"] == "Value1" && opts.Input.ContainsKey("ParentInstanceId") && (string)opts.Input["ParentInstanceId"] == parentInstanceId && - opts.Properties.ContainsKey("ParentInstanceId") && (string)opts.Properties["ParentInstanceId"] == parentInstanceId && + opts.Properties!.ContainsKey("ParentInstanceId") && (string)opts.Properties["ParentInstanceId"] == parentInstanceId && (waitForCompletion ? opts.Properties.ContainsKey("WaitForCompletion") && (bool)opts.Properties["WaitForCompletion"] : !opts.Properties.ContainsKey("WaitForCompletion")) ), Arg.Any() @@ -226,7 +226,7 @@ public class ExecuteWorkflowTests { Status = status, SubStatus = subStatus, - Output = output + Output = output ?? new Dictionary() }; var workflowResult = new RunWorkflowResult(null!, workflowState, workflow, null, Journal.Empty);