dotnet-cqrs/Svrnty.CQRS.Sagas/Builders/SagaStepDefinition.cs

150 lines
4.2 KiB
C#

using System;
using System.Threading;
using System.Threading.Tasks;
using Svrnty.CQRS.Sagas.Abstractions;
namespace Svrnty.CQRS.Sagas.Builders;
/// <summary>
/// Base class for saga step definitions.
/// </summary>
public abstract class SagaStepDefinition
{
/// <summary>
/// Unique name for this step.
/// </summary>
public string Name { get; set; } = string.Empty;
/// <summary>
/// Order of the step in the saga.
/// </summary>
public int Order { get; set; }
/// <summary>
/// Whether this step has a compensation action.
/// </summary>
public abstract bool HasCompensation { get; }
/// <summary>
/// Whether this step is a remote step (sends a command).
/// </summary>
public abstract bool IsRemote { get; }
/// <summary>
/// Timeout for this step.
/// </summary>
public TimeSpan? Timeout { get; set; }
/// <summary>
/// Maximum number of retries.
/// </summary>
public int MaxRetries { get; set; }
/// <summary>
/// Delay between retries.
/// </summary>
public TimeSpan RetryDelay { get; set; } = TimeSpan.FromSeconds(1);
}
/// <summary>
/// Definition for a local saga step.
/// </summary>
/// <typeparam name="TData">The saga data type.</typeparam>
public class LocalSagaStepDefinition<TData> : SagaStepDefinition
where TData : class, ISagaData
{
/// <summary>
/// The execution action.
/// </summary>
public Func<TData, ISagaContext, CancellationToken, Task>? ExecuteAction { get; set; }
/// <summary>
/// The compensation action.
/// </summary>
public Func<TData, ISagaContext, CancellationToken, Task>? CompensateAction { get; set; }
/// <inheritdoc />
public override bool HasCompensation => CompensateAction != null;
/// <inheritdoc />
public override bool IsRemote => false;
}
/// <summary>
/// Definition for a remote saga step.
/// </summary>
/// <typeparam name="TData">The saga data type.</typeparam>
/// <typeparam name="TCommand">The command type.</typeparam>
public class RemoteSagaStepDefinition<TData, TCommand> : SagaStepDefinition
where TData : class, ISagaData
where TCommand : class
{
/// <summary>
/// Function to build the command.
/// </summary>
public Func<TData, ISagaContext, TCommand>? CommandBuilder { get; set; }
/// <summary>
/// Handler for successful response.
/// </summary>
public Func<TData, ISagaContext, CancellationToken, Task>? ResponseHandler { get; set; }
/// <summary>
/// Type of the compensation command.
/// </summary>
public Type? CompensationCommandType { get; set; }
/// <summary>
/// Function to build the compensation command.
/// </summary>
public Func<TData, ISagaContext, object>? CompensationBuilder { get; set; }
/// <inheritdoc />
public override bool HasCompensation => CompensationBuilder != null;
/// <inheritdoc />
public override bool IsRemote => true;
}
/// <summary>
/// Definition for a remote saga step with result.
/// </summary>
/// <typeparam name="TData">The saga data type.</typeparam>
/// <typeparam name="TCommand">The command type.</typeparam>
/// <typeparam name="TResult">The result type.</typeparam>
public class RemoteSagaStepDefinition<TData, TCommand, TResult> : SagaStepDefinition
where TData : class, ISagaData
where TCommand : class
{
/// <summary>
/// Function to build the command.
/// </summary>
public Func<TData, ISagaContext, TCommand>? CommandBuilder { get; set; }
/// <summary>
/// Handler for successful response with result.
/// </summary>
public Func<TData, ISagaContext, TResult, CancellationToken, Task>? ResponseHandler { get; set; }
/// <summary>
/// Type of the compensation command.
/// </summary>
public Type? CompensationCommandType { get; set; }
/// <summary>
/// Function to build the compensation command.
/// </summary>
public Func<TData, ISagaContext, object>? CompensationBuilder { get; set; }
/// <summary>
/// The expected result type.
/// </summary>
public Type ResultType => typeof(TResult);
/// <inheritdoc />
public override bool HasCompensation => CompensationBuilder != null;
/// <inheritdoc />
public override bool IsRemote => true;
}