For the complete documentation index, see llms.txt. This page is also available as Markdown.

Tutorial

This example shows the full path for using a strongly typed message with Elsa:

  1. Define a message contract.

  2. Register the message type with the MassTransit feature.

  3. Configure a transport.

  4. Use the generated trigger and publish activities in workflows.

1. Define the message contract

OrderCreated.cs
public record OrderCreated(string OrderId, string ProductId, int Quantity);

OrderCreated is a concrete record class, so Elsa will generate both a receive trigger and a publish activity for it.

That detail matters in release/3.8.0: the generated MessageReceived activity compares the incoming message's exact runtime type to the configured MessageType, so concrete record or class contracts are the safest choice.

2. Register the message type and configure MassTransit

Program.cs
builder.Services.AddElsa(elsa => elsa
    .UseMassTransit(massTransit =>
    {
        massTransit.AddMessageType<OrderCreated>();

        // Use a broker for cross-process messaging.
        massTransit.UseRabbitMq(rabbitMqConnectionString);
    }));

With that configuration, Elsa adds two activities:

  • Order Created

  • Publish Order Created

If you omit UseRabbitMq(...) or another transport configuration method, Elsa falls back to MassTransit's in-memory transport.

If you want to control throughput or temporary queue lifetime, configure MassTransitOptions in the host as well:

3. Start a workflow when the message arrives

Use the generated Order Created trigger activity at the start of a workflow and mark it as a start trigger in Studio.

In code, the equivalent looks like this:

When a MassTransit consumer receives OrderCreated, Elsa resumes or starts matching workflows by sending a stimulus that contains the message payload.

The message is also exposed as the activity result, so downstream activities can read it through the output or through a workflow variable, as shown above.

4. Publish the message from a workflow

Use the generated Publish Order Created activity when a workflow needs to emit the message:

In Studio, the equivalent activity is Publish Order Created.

Because OrderCreated is a class, Elsa generates both the trigger and publish activities.

5. Deployment notes

  • Keep consumers enabled on nodes that should process broker messages.

  • Set massTransit.DisableConsumers = true on nodes that should host the API but not consume workflow messages.

  • If you also move Elsa runtime dispatch over MassTransit, configure UseMassTransitDispatcher() separately on workflow management and runtime features. Registering message types alone does not enable dispatcher-based workflow execution.

  • Tune queue and broker throughput with MassTransitOptions and the transport configurator callbacks.

6. Troubleshooting checklist

  • If the activities do not appear, verify AddMessageType<OrderCreated>() runs during startup.

  • If messages publish but workflows do not start, verify consumers are enabled on the running node and that the trigger is marked as a start trigger.

  • If a message reaches MassTransit but Elsa does not resume the workflow, verify the registered contract is the concrete runtime type being consumed.

  • If you use a real broker, verify the relevant RabbitMQ or Azure Service Bus transport package is installed and configured.

  • If correlation matters, confirm the producer sets a MassTransit CorrelationId that matches your workflow design.

When to use this pattern

Use this pattern when:

  • your application already uses MassTransit contracts between services

  • you want workflows to react to or emit strongly typed domain messages

  • you want the same broker to work across processes or nodes

Use a transport-specific module instead when you need broker-specific concepts such as Azure Service Bus queues, topics, or subscriptions.

Last updated