Home > Software design >  Raise event from activity
Raise event from activity

Time:01-31

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.

  • Related