Search code examples
c#.netmasstransitstate-machineautomatonymous

How to avoid persisting a temporary conditional variable when MassTransit Automatonymous is using Entity Framework


I am using Mass Transit's FSM Automatonymous package to persist the saga state into a database via Entity Framework integration, so I have a saga class mapped to a DB table containing correlation ID, saga state, a couple of timestamps. That's all working OK.

I have come to implement a conditional transition which previously I've solved using a two step process, after reading various other people's solutions:

  1. query the condition and store the result in a temporary variable in the saga instance
  2. use the ifelse(condition, func, func) to branch to either next state

Previously I was using an in-memory saga repository, so adding another variable to the saga instance class wasn't a bit deal. But now my saga instance class is an EF bound model and so I would therefore need to add another column to the database and refresh the model etc. I could do that, but I'd like to avoid littering the tables (and the persistence model generally) with what really should be a very momentary in-memory variable.

Specifically, my FSM is performing a checkup of a remote service which replies to commands with responses, and we check if they replied correctly or not.

So I want to do something like this:

        When(DoTheProcessMessage)
            .Then(context => {
                context.Instance.ValidationResult = service.validateResponse(context.Data.command, context.Data.response);
            })
            .IfElse(context => context.Instance.ValidationResult,
                binder => binder
                    .TransitionTo(ContinueSomeProcess),
                binder => binder
                    .TransitionTo(StartValidationFailureRepairProcess)
            ),

Which means I have to add ValidationResult to my data model and DB schema, but it's only needed to "bridge" those two lines.

Is there another way to perform an if-else transition without having to store the result in the instance?

I am currently stuck on v5 of Mass Transit due to other dependencies.

I have read


Solution

  • While writing this question I figured it out - it's so obvious it's stupid!

    I can just embed the conditional query function in the IfElse itself, there's no need to temporarily store it in the instance. I was just following examples where the condition had already been stored in the instance, and imagined the IfElse could only access context data or something.

            When(DoTheProcessMessage)
                .IfElse(context => service.validateResponse(context.Data.command, context.Data.response),
                    binder => binder
                        .TransitionTo(ContinueSomeProcess),
                    binder => binder
                        .TransitionTo(StartValidationFailureRepairProcess)
                ),