Skip to main content
The Eventing Modeler extends the Services designer to support modeling message-based integration patterns. It enables you to design event-driven architectures, integration events, commands, and event handlers for building distributed and decoupled systems.

Overview

The Eventing Modeler is based on the Intent.Modelers.Eventing module, which provides:
  • Visual modeling of integration messages (events and commands)
  • Event handler modeling
  • Publish-subscribe patterns
  • Message-based integration between services
  • Support for message brokers (RabbitMQ, Kafka, Azure Service Bus, etc.)
  • Event-driven architecture patterns

Designer Configuration

The Eventing capabilities extend the Services designer with eventing-specific elements:
  • Module ID: Intent.Modelers.Eventing
  • Extends: Services Designer
  • Core Types: Integration events, integration commands, event handlers, message subscriptions

What is Message-Based Integration?

Message-based integration is a design approach where systems communicate asynchronously by exchanging messages through a message broker. This approach:
  • Decouples Systems: Services operate independently without direct dependencies
  • Improves Scalability: Components can scale independently
  • Enhances Fault Tolerance: Systems remain resilient when services are temporarily unavailable
  • Enables Flexibility: Easy to add new services or modify existing ones
Common Use Cases:
  • Processing orders asynchronously
  • Handling events across microservices
  • Coordinating distributed workflows
  • Real-time notifications and updates

Core Elements

Message

Messages are the base type for integration events and commands. Properties:
  • Name: Message name
  • Properties: Data fields carried by the message
  • Folder: Organization folder
Example Usage:
var message = element.AsMessageModel();
var properties = message.Properties;

Integration Event

Integration events represent notifications about something that has happened in the system. Characteristics:
  • Past-tense naming (e.g., OrderPlaced, PaymentProcessed)
  • Published by one service
  • Can have multiple subscribers
  • Represents a fact that occurred
Example Events:
  • CustomerRegistered
  • OrderShipped
  • PaymentFailed
  • InventoryUpdated

Integration Command

Integration commands represent requests to perform an action in another service. Characteristics:
  • Imperative naming (e.g., ProcessPayment, UpdateInventory)
  • Published by one service
  • Typically has one handler
  • Represents an intent or request
Example Commands:
  • ProcessPayment
  • SendNotification
  • UpdateCustomerDetails
  • ReserveInventory

Event Handler

Event handlers subscribe to and process integration events or commands. Properties:
  • Name: Handler name
  • Subscribed Messages: Events or commands this handler processes
  • Operations: Logic to execute when message is received
Example Usage:
var handler = element.AsEventHandlerModel();
var subscribedEvents = handler.SubscribedMessages;

Message Publish Association

Represents publishing an integration message from a service operation. Usage: Draw an association from a Command/Query to an Integration Event/Command to indicate that the operation publishes that message.

Message Subscribe Association

Represents subscribing to an integration message. Usage: Draw an association from an Event Handler to an Integration Event/Command to indicate that the handler subscribes to that message.

Modeling Patterns

Publishing Integration Events

When a service operation completes, it can publish an event to notify other services. Steps:
  1. Create an Integration Event (e.g., OrderPlaced)
  2. Add properties to the event (OrderId, CustomerId, Total)
  3. Find the Command that triggers this event (e.g., CreateOrder)
  4. Draw a “Publish” association from the Command to the Integration Event
  5. Optionally configure mapping between command result and event properties
Example:
CreateOrder (Command)
  └─ Publishes → OrderPlaced (Integration Event)
      ├─ OrderId: Guid
      ├─ CustomerId: Guid
      ├─ Total: decimal
      └─ OrderDate: DateTime

Subscribing to Integration Events

Services can react to events published by other services. Steps:
  1. Create an Event Handler (e.g., OrderPlacedHandler)
  2. Create or reference the Integration Event (e.g., OrderPlaced)
  3. Draw a “Subscribe” association from the Event Handler to the Integration Event
  4. Add operations to the handler to define processing logic
Example:
OrderPlacedHandler (Event Handler)
  ├─ Subscribes → OrderPlaced (Integration Event)
  └─ Operations:
      ├─ UpdateInventory()
      └─ SendConfirmationEmail()

Sending Integration Commands

A service can send a command to another service to request an action. Steps:
  1. Create an Integration Command (e.g., ProcessPayment)
  2. Add properties (OrderId, Amount, PaymentMethod)
  3. From a service operation, draw a “Publish” association to the Integration Command
  4. Create an Event Handler in the target service to process the command
Example:
PlaceOrder (Command)
  └─ Sends → ProcessPayment (Integration Command)
      ├─ OrderId: Guid
      ├─ Amount: decimal
      └─ PaymentMethod: string

ProcessPaymentHandler (Event Handler)
  ├─ Subscribes → ProcessPayment (Integration Command)
  └─ ProcessPayment() operation

Saga/Workflow Pattern

Coordinate multi-step distributed transactions. Example: Order Processing Saga
1. PlaceOrder (Command)
   └─ Publishes → OrderPlaced (Event)

2. OrderPlacedHandler
   └─ Sends → ReserveInventory (Command)

3. InventoryReservedHandler
   └─ Sends → ProcessPayment (Command)

4. PaymentProcessedHandler
   └─ Publishes → OrderConfirmed (Event)

Compensation:
   PaymentFailed (Event)
   └─ Triggers → ReleaseInventory (Command)

Event-Driven Architecture Patterns

Event Notification

Simple notification that something happened. Use Case: Notify systems when data changes Pattern:
  • Publisher: Emits event with minimal data
  • Subscribers: React to event, potentially querying for more details

Event-Carried State Transfer

Events carry complete state data. Use Case: Avoid queries back to source system Pattern:
  • Publisher: Includes full entity state in event
  • Subscribers: Update local cache/replica from event data

Event Sourcing

Store state as sequence of events. Use Case: Audit trail, temporal queries, replay capability Pattern:
  • Commands generate events
  • Events are persisted as source of truth
  • Current state derived by replaying events

Metadata API

Accessing Eventing Models

using Intent.Modelers.Eventing.Api;

var eventingPackage = model.GetEventingPackageModel();
var messages = eventingPackage.Messages;
var integrationCommands = eventingPackage.IntegrationCommands;

Working with Messages

var message = element.AsMessageModel();
var name = message.Name;
var properties = message.Properties;

foreach (var prop in properties)
{
    var propName = prop.Name;
    var propType = prop.TypeReference.Element.Name;
}

Working with Event Handlers

var handler = element.AsEventHandlerModel();
var subscribedMessages = handler.GetSubscribedMessages();

foreach (var message in subscribedMessages)
{
    // Generate subscription code
}

Detecting Publish Operations

var command = element.AsCommandModel();
var publishedMessages = command.GetPublishedMessages();

foreach (var message in publishedMessages)
{
    // Generate message publishing code
}

Integration with Message Brokers

The Eventing Modeler is technology-agnostic, supporting various message brokers through Intent Architect modules:

RabbitMQ

  • Topic exchanges for events
  • Direct exchanges for commands
  • Queue configuration
  • Retry and dead-letter handling

Azure Service Bus

  • Topics for events
  • Queues for commands
  • Sessions and correlation
  • Scheduled messages

Kafka

  • Topics for events
  • Consumer groups
  • Partitioning strategies
  • Offset management

Amazon SQS/SNS

  • SNS topics for events
  • SQS queues for consumers
  • Fan-out patterns

Common Modeling Scenarios

Microservice Communication

Scenario: Order Service notifies Inventory Service
  1. In Order Service designer:
    • Create CreateOrder command
    • Create OrderPlaced integration event
    • Add properties: OrderId, CustomerId, Items[]
    • Link command to publish event
  2. In Inventory Service designer:
    • Reference or create OrderPlaced event
    • Create OrderPlacedHandler event handler
    • Subscribe handler to event
    • Add UpdateInventory operation to handler

Distributed Transaction

Scenario: Payment processing workflow
  1. Create events:
    • PaymentRequested
    • PaymentProcessed
    • PaymentFailed
  2. Create commands:
    • ProcessPayment
    • RefundPayment
  3. Create handlers:
    • PaymentRequestedHandler → Sends ProcessPayment
    • PaymentProcessedHandler → Updates order status
    • PaymentFailedHandler → Triggers compensation

Event Fan-Out

Scenario: Single event, multiple handlers
  1. Create event: CustomerRegistered
  2. Create multiple handlers:
    • SendWelcomeEmailHandler
    • CreateLoyaltyAccountHandler
    • UpdateAnalyticsHandler
  3. Subscribe all handlers to the same event

Integration with Modules

The Eventing Modeler integrates with:
  • MassTransit Module: Generate MassTransit-based messaging
  • NServiceBus Module: Generate NServiceBus endpoints and handlers
  • Azure Service Bus Module: Generate Azure Service Bus clients
  • RabbitMQ Module: Generate RabbitMQ consumers and publishers
  • Event Sourcing Modules: Generate event sourcing infrastructure

Best Practices

  1. Event Naming: Use past-tense for events (e.g., OrderPlaced), imperative for commands (e.g., PlaceOrder)
  2. Event Schema: Include essential data in events; avoid excessive payloads
  3. Idempotency: Design handlers to be idempotent (safe to process multiple times)
  4. Versioning: Plan for event schema evolution from the start
  5. Error Handling: Model compensation events for saga rollback
  6. Correlation: Include correlation IDs to trace distributed workflows
  7. Documentation: Add comments explaining event semantics and expected handlers
  8. Boundaries: Keep integration events at bounded context boundaries
  9. Granularity: Events should represent meaningful business facts
  10. Testing: Model both happy path and failure scenarios

Example Eventing Model

A typical e-commerce eventing model:
Integration Events:
- CustomerRegistered
  └─ CustomerId, Email, RegisteredDate
  
- OrderPlaced
  └─ OrderId, CustomerId, Items[], Total
  
- PaymentProcessed
  └─ PaymentId, OrderId, Amount
  
- OrderShipped
  └─ OrderId, TrackingNumber, ShipDate

Integration Commands:
- ProcessPayment
  └─ OrderId, Amount, PaymentMethod
  
- UpdateInventory
  └─ ProductId, Quantity, Operation
  
- SendNotification
  └─ RecipientId, NotificationType, Message

Event Handlers:
- OrderPlacedHandler
  ├─ Subscribes to: OrderPlaced
  └─ Publishes: ProcessPayment, UpdateInventory
  
- PaymentProcessedHandler
  ├─ Subscribes to: PaymentProcessed
  └─ Publishes: SendNotification, OrderConfirmed