150 lines
4.2 KiB
C#
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;
|
|
}
|