I'm building a saga state machine, trimmed down implementation below:
public class DueDiligenceCaseCreateStateMachine : MassTransitStateMachine<DueDiligenceCaseCreateState>
{
public State CreatingCase { get; private set; }
public Event<DueDiligenceCaseCreateCommand> TriggerReceived { get; private set; }
public Event CaseCreationFinished { get; private set; }
public Event CaseCreationFailed { get; private set; }
private readonly ILogger<DueDiligenceCaseCreateStateMachine> _logger;
private readonly IOptions<DueDiligenceCaseCreateSagaOptions> _sagaOptions;
public DueDiligenceCaseCreateStateMachine(
ILogger<DueDiligenceCaseCreateStateMachine> logger,
IOptions<DueDiligenceCaseCreateSagaOptions> sagaOptions)
{
_logger = logger;
_sagaOptions = sagaOptions;
Configure();
BuildProcess();
}
private void Configure()
{
Event(
() => TriggerReceived,
e => e.CorrelateById(x => x.Message.DueDiligenceCaseId));
}
private void BuildProcess()
{
During(
Initial,
When(TriggerReceived)
.TransitionTo(CreatingCase)
.Activity(CreateCase));
}
private EventActivityBinder<DueDiligenceCaseCreateState, DueDiligenceCaseCreateCommand> CreateCase(
IStateMachineActivitySelector<DueDiligenceCaseCreateState, DueDiligenceCaseCreateCommand> sel) =>
sel.OfType<CreateCaseActivity>();
}
And the activity itself is here:
public class CreateCaseActivity : BaseActivity<DueDiligenceCaseCreateState, DueDiligenceCaseCreateCommand>
{
private readonly ICommandHandler<InitializeCaseCommand> _initializeCaseHandler;
private readonly IOptions<ApplicationOptions> _options;
private readonly ILogger<DueDiligenceCaseCreateConsumer> _logger;
public CreateCaseActivity(
ICommandHandler<InitializeCaseCommand> initializeCaseHandler,
IOptions<ApplicationOptions> options,
ILogger<DueDiligenceCaseCreateConsumer> logger)
{
_initializeCaseHandler = initializeCaseHandler;
_options = options;
_logger = logger;
}
public override async Task Execute(
BehaviorContext<DueDiligenceCaseCreateState, DueDiligenceCaseCreateCommand> context,
Behavior<DueDiligenceCaseCreateState, DueDiligenceCaseCreateCommand> next)
{
_logger.LogInformation(
"Consuming {Command} started, case id: {caseid}, creating a case...",
nameof(DueDiligenceCaseCreateCommand),
context.Data.DueDiligenceCaseId);
var initializeCaseCmd = ConvertMessageToCommand(context.Data);
initializeCaseCmd.CanHaveOnlyOneActiveCasePerCustomer = !_options.Value.FeatureToggles.AllowMultipleActiveCasesOnSingleCustomer;
try
{
await _initializeCaseHandler.Handle(initializeCaseCmd);
}
catch
{
}
finally
{
await next.Execute(context);
}
}
private InitializeCaseCommand ConvertMessageToCommand(DueDiligenceCaseCreateCommand message) =>
// returns the command object
}
The state machine has two events for now - CaseCreationFinished
and CaseCreationFailed
. I'd like to raise the first one in the try
clause of the activity and the other one in the catch
part. I see the context object passed in as an argument has the Raise
method, but the problem is that I can't reach the DueDiligenceCaseCreateStateMachine.CaseCreationFinished from within the activity. Is there a way to do it?
CodePudding user response:
There is a Raise
method on BehaviorContext
, why not use it?
Updated
You can add a dependency on your activity for the state machine itself, which would give you access to the events.