diff --git a/README.md b/README.md index 131a4a1..8bf7360 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,12 @@ Chronicle is simple **process manager/saga pattern** implementation for .NET Cor Chornicle is available on [NuGet](https://www.nuget.org/packages/Chronicle_/) ### Package manager ```bash -Install-Package Chronicle_ -Version 3.1.0 +Install-Package Chronicle_ -Version 3.2.1 ``` ### .NET CLI ```bash -dotnet add package Chronicle_ --version 3.1.0 +dotnet add package Chronicle_ --version 3.2.1 ``` # Getting started diff --git a/src/Chronicle/Builders/ChronicleBuilder.cs b/src/Chronicle/Builders/ChronicleBuilder.cs index c627eeb..5a4e614 100644 --- a/src/Chronicle/Builders/ChronicleBuilder.cs +++ b/src/Chronicle/Builders/ChronicleBuilder.cs @@ -1,5 +1,3 @@ -using System; -using Chronicle.Errors; using Chronicle.Persistence; using Microsoft.Extensions.DependencyInjection; diff --git a/src/Chronicle/Chronicle.csproj b/src/Chronicle/Chronicle.csproj index 062f135..aa237dc 100644 --- a/src/Chronicle/Chronicle.csproj +++ b/src/Chronicle/Chronicle.csproj @@ -11,10 +11,10 @@ https://github.com/chronicle-stack/Chronicle https://github.com/chronicle-stack/Chronicle/blob/master/LICENSE https://avatars1.githubusercontent.com/u/42150754?s=200 - 3.1.0 - 3.1.0 - 3.1.0.0 - 3.1.0.0 + 3.2.1 + 3.2.1 + 3.2.1.0 + 3.2.1.0 latest diff --git a/src/Chronicle/ChronicleException.cs b/src/Chronicle/ChronicleException.cs index d529160..b5a867f 100644 --- a/src/Chronicle/ChronicleException.cs +++ b/src/Chronicle/ChronicleException.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics.Tracing; namespace Chronicle { @@ -7,7 +6,10 @@ public class ChronicleException : Exception { public ChronicleException(string message) : base(message) { - + } + + public ChronicleException(string message, Exception innerException) : base(message, innerException) + { } } } diff --git a/src/Chronicle/Extensions.cs b/src/Chronicle/Extensions.cs index 62d3ddf..e6b6ba8 100644 --- a/src/Chronicle/Extensions.cs +++ b/src/Chronicle/Extensions.cs @@ -37,10 +37,10 @@ public static IServiceCollection AddChronicle(this IServiceCollection services, private static void RegisterSagas(this IServiceCollection services) => services.Scan(scan => { - var assembly = Assembly.GetEntryAssembly(); + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); scan - .FromAssemblies(assembly) + .FromAssemblies(assemblies) .AddClasses(classes => classes.AssignableTo(typeof(ISaga))) .As(t => t .GetTypeInfo() diff --git a/src/Chronicle/IChronicleBuilder.cs b/src/Chronicle/IChronicleBuilder.cs index 3711582..c24b649 100644 --- a/src/Chronicle/IChronicleBuilder.cs +++ b/src/Chronicle/IChronicleBuilder.cs @@ -1,4 +1,3 @@ -using System; using Microsoft.Extensions.DependencyInjection; namespace Chronicle diff --git a/src/Chronicle/ISaga.cs b/src/Chronicle/ISaga.cs index fa808f0..194e9ca 100644 --- a/src/Chronicle/ISaga.cs +++ b/src/Chronicle/ISaga.cs @@ -1,3 +1,4 @@ +using System; using System.Threading.Tasks; namespace Chronicle @@ -8,8 +9,8 @@ public interface ISaga SagaStates State { get; } void Complete(); Task CompleteAsync(); - void Reject(); - Task RejectAsync(); + void Reject(Exception innerException = null); + Task RejectAsync(Exception innerException = null); void Initialize(SagaId id, SagaStates state); SagaId ResolveId(object message, ISagaContext context); } diff --git a/src/Chronicle/Managers/SagaCoordinator.cs b/src/Chronicle/Managers/SagaCoordinator.cs index 60f940f..9e877b8 100644 --- a/src/Chronicle/Managers/SagaCoordinator.cs +++ b/src/Chronicle/Managers/SagaCoordinator.cs @@ -1,11 +1,7 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Threading; using System.Threading.Tasks; using Chronicle.Async; -using Chronicle.Persistence; -using Chronicle.Utils; namespace Chronicle.Managers { @@ -17,7 +13,7 @@ internal sealed class SagaCoordinator : ISagaCoordinator private readonly ISagaPostProcessor _postProcessor; private static readonly KeyedLocker Locker = new KeyedLocker(); - public SagaCoordinator(ISagaSeeker seeker, ISagaInitializer initializer, ISagaProcessor processor, + public SagaCoordinator(ISagaSeeker seeker, ISagaInitializer initializer, ISagaProcessor processor, ISagaPostProcessor postProcessor) { _seeker = seeker; @@ -26,23 +22,21 @@ public SagaCoordinator(ISagaSeeker seeker, ISagaInitializer initializer, ISagaPr _postProcessor = postProcessor; } - public Task ProcessAsync(TMessage message, ISagaContext context = null) where TMessage : class + public Task ProcessAsync(TMessage message, ISagaContext context = null) where TMessage : class => ProcessAsync(message: message, onCompleted: null, onRejected: null, context: context); public async Task ProcessAsync(TMessage message, Func onCompleted = null, Func onRejected = null, ISagaContext context = null) where TMessage : class { var actions = _seeker.Seek().ToList(); - var sagaTasks = new List(); Task EmptyHook(TMessage m, ISagaContext ctx) => Task.CompletedTask; - onCompleted = onCompleted ?? EmptyHook; - onRejected = onRejected ?? EmptyHook; + onCompleted ??= EmptyHook; + onRejected ??= EmptyHook; - foreach (var action in actions) - { - sagaTasks.Add(ProcessAsync(message, action, onCompleted, onRejected, context)); - } + var sagaTasks = actions + .Select(action => ProcessAsync(message, action, onCompleted, onRejected, context)) + .ToList(); await Task.WhenAll(sagaTasks); } @@ -51,7 +45,7 @@ private async Task ProcessAsync(TMessage message, ISagaAction onCompleted, Func onRejected, ISagaContext context = null) where TMessage : class { - context = context ?? SagaContext.Empty; + context ??= SagaContext.Empty; var saga = (ISaga)action; var id = saga.ResolveId(message, context); @@ -63,7 +57,7 @@ private async Task ProcessAsync(TMessage message, ISagaAction(ISaga saga, TMessage message, ISagaState state, + + public async Task ProcessAsync(ISaga saga, TMessage message, ISagaState state, ISagaContext context) where TMessage : class { var action = (ISagaAction)saga; @@ -24,13 +24,13 @@ public async Task ProcessAsync(ISaga saga, TMessage message, ISagaStat { await action.HandleAsync(message, context); } - catch (Exception e) + catch (Exception ex) { - context.SagaContextError = new SagaContextError(e); + context.SagaContextError = new SagaContextError(ex); if (!(saga.State is SagaStates.Rejected)) { - saga.Reject(); + saga.Reject(ex); } } finally @@ -38,7 +38,7 @@ public async Task ProcessAsync(ISaga saga, TMessage message, ISagaStat await UpdateSagaAsync(message, saga, state); } } - + private async Task UpdateSagaAsync(TMessage message, ISaga saga, ISagaState state) where TMessage : class { @@ -51,7 +51,7 @@ private async Task UpdateSagaAsync(TMessage message, ISaga saga, ISaga var persistenceTasks = new [] { - _repository.WriteAsync(state), + _repository.WriteAsync(state), _log.WriteAsync(logData) }; diff --git a/src/Chronicle/Managers/SagaSeeker.cs b/src/Chronicle/Managers/SagaSeeker.cs index 1106649..558c334 100644 --- a/src/Chronicle/Managers/SagaSeeker.cs +++ b/src/Chronicle/Managers/SagaSeeker.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; namespace Chronicle.Managers diff --git a/src/Chronicle/Saga.cs b/src/Chronicle/Saga.cs index d735e22..db5c39a 100644 --- a/src/Chronicle/Saga.cs +++ b/src/Chronicle/Saga.cs @@ -24,15 +24,15 @@ public virtual Task CompleteAsync() return Task.CompletedTask; } - public virtual void Reject() + public virtual void Reject(Exception innerException = null) { State = SagaStates.Rejected; - throw new ChronicleException("Saga rejection called by method"); + throw new ChronicleException("Saga rejection called by method", innerException); } - public virtual Task RejectAsync() + public virtual Task RejectAsync(Exception innerException = null) { - Reject(); + Reject(innerException); return Task.CompletedTask; } }