### PostgreSQL Connection String Example Source: https://masstransit.massient.com/configuration/transports/sql Example of a PostgreSQL connection string configuration in appsettings.json. ```json { "ConnectionStrings": { "Db": "Server=localhost;Port=5432;user id=postgres;password=Password12!;database=my_app;" }, "AllowedHosts": "*" } ``` -------------------------------- ### Submit Order Consumer Example Source: https://masstransit.massient.com/configuration/middleware/retry An example consumer that processes orders and commits a transaction. ```csharp public class SubmitOrderConsumer : IConsumer { ISessionFactory _sessionFactory; public async Task Consume(ConsumeContext context) { using(var session = _sessionFactory.OpenSession()) using(var transaction = session.BeginTransaction()) { var customer = session.Get(context.Message.CustomerId); // continue with order processing transaction.Commit(); } } } ``` -------------------------------- ### Install MassTransit Quartz Package Source: https://masstransit.massient.com/configuration/schedulers/quartz Add the required NuGet package to your project. ```bash dotnet add package MassTransit.Quartz ``` -------------------------------- ### Configure Quartz.NET Basic Setup Source: https://masstransit.massient.com/configuration/schedulers/quartz Register Quartz and MassTransit services for development or simple deployments. ```csharp services.AddQuartz(); ``` ```csharp services.AddMassTransit(x => { x.AddPublishMessageScheduler(); x.AddQuartzConsumers(); x.UsingRabbitMq((context, cfg) => { cfg.UsePublishMessageScheduler(); cfg.ConfigureEndpoints(context); }); }); ``` -------------------------------- ### Register Kafka Producer and Produce Messages Source: https://masstransit.massient.com/configuration/transports/kafka Registers a Kafka producer and demonstrates producing messages to a specified topic. This example includes basic MassTransit setup and a loop for user input. ```csharp namespace KafkaProducer; using System; using System.Threading; using System.Threading.Tasks; using MassTransit; using Microsoft.Extensions.DependencyInjection; public class Program { public static async Task Main() { var services = new ServiceCollection(); services.AddMassTransit(x => { x.UsingInMemory(); x.AddRider(rider => { rider.AddProducer("topic-name"); rider.UsingKafka((context, k) => { k.Host("localhost:9092"); }); }); }); var provider = services.BuildServiceProvider(); var busControl = provider.GetRequiredService(); await busControl.StartAsync(new CancellationTokenSource(TimeSpan.FromSeconds(10)).Token); try { var producer = provider.GetRequiredService>(); do { string value = await Task.Run(() => { Console.WriteLine("Enter text (or quit to exit)"); Console.Write("> "); return Console.ReadLine(); }); if ("quit".Equals(value, StringComparison.OrdinalIgnoreCase)) break; await producer.Produce(new { Text = value }); } while (true); } finally { await busControl.StopAsync(); } } public record KafkaMessage { public string Text { get; init; } } } ``` -------------------------------- ### Submit Order Consumer Example Source: https://masstransit.massient.com/configuration/message-route An example of a consumer that processes a `SubmitOrder` message and then sends a `StartDelivery` message, utilizing endpoint conventions for routing. ```csharp public class SubmitOrderConsumer : IConsumer { private readonly IOrderSubmitter _orderSubmitter; public SubmitOrderConsumer(IOrderSubmitter submitter) => _orderSubmitter = submitter; public async Task Consume(IConsumeContext context) { await _orderSubmitter.Process(context.Message); await context.Send(new StartDelivery(context.Message.OrderId, DateTime.UtcNow)); } } ``` -------------------------------- ### Basic Unit Test Setup with Test Harness Source: https://masstransit.massient.com/guides/unit-testing This is the minimum setup for a unit test using the MassTransit Test Harness. It assumes the in-memory transport and configures the bus endpoints automatically. ```csharp [Test] public async Task A_complete_unit_test() { await using var provider = new ServiceCollection() .AddMassTransitTestHarness(x => { }) .BuildServiceProvider(true); var harness = await provider.StartTestHarness(); } ``` -------------------------------- ### Activity Compensation Log Example Source: https://masstransit.massient.com/guides/routing-slips An example of returning compensation data from the Compensate method. This data is used to reverse the activity's effects. ```csharp return context.Completed(new LogModel { SomeData = "abc" }) ``` -------------------------------- ### Example SubmitOrderConsumer Source: https://masstransit.massient.com/concepts/consumers An example implementation of an `IConsumer` that consumes the `SubmitOrder` message type and publishes an `OrderSubmitted` event. ```csharp class SubmitOrderConsumer : IConsumer { public async Task Consume(ConsumeContext context) { await context.Publish(new { context.Message.OrderId }); } } ``` -------------------------------- ### Install Serilog NuGet Packages Source: https://masstransit.massient.com/configuration/logging Required packages for Serilog integration with console output. ```bash dotnet add package Serilog.Extensions.Hosting dotnet add package Serilog dotnet add package Serilog.Sinks.Console ``` -------------------------------- ### Full ASP.NET Core Integration Source: https://masstransit.massient.com/configuration/schedulers/quartz Complete setup for Quartz.NET and MassTransit in an ASP.NET Core application. ```csharp var builder = WebApplication.CreateBuilder(args); var connectionString = builder.Configuration.GetConnectionString("quartz") ?? throw new InvalidOperationException("Connection string 'quartz' is not configured."); // Configure Quartz with SQL Server and clustering builder.Services.AddQuartz(q => { q.SchedulerName = "MassTransit-Scheduler"; q.SchedulerId = "AUTO"; q.UseDefaultThreadPool(tp => { tp.MaxConcurrency = 10; }); q.UsePersistentStore(s => { s.UseProperties = true; s.RetryInterval = TimeSpan.FromSeconds(15); s.UseSqlServer(connectionString); s.UseClustering(c => { c.CheckinMisfireThreshold = TimeSpan.FromSeconds(20); c.CheckinInterval = TimeSpan.FromSeconds(10); }); }); }); // Add MassTransit with Quartz builder.Services.AddMassTransit(x => { x.AddPublishMessageScheduler(); x.AddConsumers(typeof(Program).Assembly); x.AddQuartzConsumers(); x.UsingRabbitMq((context, cfg) => { cfg.Host(builder.Configuration.GetConnectionString("RabbitMq")); cfg.UsePublishMessageScheduler(); cfg.ConfigureEndpoints(context); }); }); // Start Quartz scheduler builder.Services.AddQuartzHostedService(options => { options.StartDelay = TimeSpan.FromSeconds(5); options.WaitForJobsToComplete = true; }); var app = builder.Build(); app.UseRouting(); app.UseAuthorization(); app.MapControllers(); app.MapHealthChecks("/health/ready"); app.Run(); ``` -------------------------------- ### Receive Endpoint Started Function Source: https://masstransit.massient.com/reference/sql-functions Registers startup settings for PostgreSQL receive endpoints, including notification and queue-touch throttle intervals. ```sql receive_endpoint_started(p_queue_id bigint, p_notify_throttle interval, p_touch_throttle interval DEFAULT NULL) ``` -------------------------------- ### Initialize Routing Slip Builder Source: https://masstransit.massient.com/guides/routing-slips/build Basic initialization of a RoutingSlipBuilder instance using a new GUID. ```csharp var builder = new RoutingSlipBuilder(NewId.NextGuid()); var routingSlip = builder.Build(); ``` -------------------------------- ### Install MassTransit Hangfire Packages Source: https://masstransit.massient.com/configuration/schedulers/hangfire Install the core MassTransit Hangfire package and the required storage provider for your database backend. ```bash dotnet add package MassTransit.Hangfire ``` ```bash # Choose one of the following: dotnet add package Hangfire.SqlServer # SQL Server dotnet add package Hangfire.Redis.StackExchange # Redis dotnet add package Hangfire.PostgreSQL # PostgreSQL ``` -------------------------------- ### Example License Key Format Source: https://masstransit.massient.com/configuration/license The license key file format required for MassTransit v9+. ```text -----BEGIN LICENSE KEY----- c1SDNOXHUwMDJCTUFkSVRqTExWSzMwc0xiUkxMM0JDa3ZhWUpXWFNUbXJ3N1x1MDAyQmRFRjR0 WnZiblJ2WW1Wc0lpd2laVzFoYVd3aU9pSnpkRtWVc0dVpHRmxkSGQ1YkdWeVFIWnZiblJ2WW1W T2lJeU1ESMVEV5TFRBNVZEQXdPakF3T2pBd1dpSXNJbVY0Y0dseVpYTWlPaUl5TURJM0xUQXhM eyJ2ZXJzaW9uIjojEiLCJraW5kIjoiTGljZW5zZSIsIm1ldGEiOnsic2lnbmF0dXJlLWFsZ29y c0xtTnZiU0o5TENKamRYTjMjFsY2lJNmV5SnBaQ0k2SW1OMWMxOVVXbHBIYzFCUVlrOW1jRzR4 T0NJc0ltNWhiV1VpT2lKQ1lXNJRlp2Ym5SdlltVnNJbjBzSW5CeWIyUjFZM1J6SWpwN0ltMWhj OXVJam9pVFdGemMxUnlZV6YVhRZ1RHbGpaVzV6WlNJc0ltVjRjR2x5WlhNaU9pSXlNREkyTFRF eUxUQTVWREF3T2pBd09qdXaUlzSW1abFlYUjFjbVZ6SWpwdWRXeHNmWDBzSW1OeVpXRjBaV1Fp VEE0VkRBd09qQXdPakF3lKOSIsInNpZ25hdHVyZSI6IkFYMVRJNWE2c1dMZXVoNi9rLzcxNk8v aXRobSI6IkVDRHNhIn0sImRhdGEiJleUpqYjI1MFlXTjBJanA3SW01aGJXVWlPaUpDWVc1cklG M04wY21GdWMybDBJanA3SW01aGJXVWlPpOWVhOelZISmhibk5wZENJc0ltUmxjMk55YVhCMGFX VWJMMTF1R0libXd2YjlWR2ZhUTlkZ1FERExseDQUdrMVBvdmhaRkN2ajdWbDlQVFNiVkFFdUE3 -----END LICENSE KEY----- ``` -------------------------------- ### Configure middleware in bus setup Source: https://masstransit.massient.com/guides/middleware Demonstrates how to register the custom filter extension method within the bus configuration. ```csharp x.UsingInMemory((context,cfg) => { cfg.UseExceptionLogger(); // <-- our new method cfg.ConfigureEndpoints(context); }); ``` -------------------------------- ### Configure Bus Endpoint AutoStart Source: https://masstransit.massient.com/concepts/requests Set `AutoStart = true` to ensure the bus endpoint starts when the bus is initialized, reducing the latency of the first request. This is useful when the request client is frequently used. ```csharp services.AddMassTransit(x => { x.UsingRabbitMq((context, cfg) => { cfg.AutoStart = true; // default = false, starts the bus endpoint with the bus }); }); ``` -------------------------------- ### Full ASP.NET Core Integration Source: https://masstransit.massient.com/configuration/schedulers/hangfire Complete setup for MassTransit with Hangfire storage and dashboard configuration. ```csharp var builder = WebApplication.CreateBuilder(args); // Configure Hangfire with SQL Server storage builder.Services.AddHangfire(h => h .UseRecommendedSerializerSettings() .UseSqlServerStorage(builder.Configuration.GetConnectionString("Hangfire"))); builder.Services.AddHangfireServer(); // Add MassTransit with Hangfire builder.Services.AddMassTransit(x => { x.AddPublishMessageScheduler(); x.AddConsumers(typeof(Program).Assembly); x.AddHangfireConsumers(); x.UsingRabbitMq((context, cfg) => { cfg.Host(builder.Configuration.GetConnectionString("RabbitMq")); cfg.UsePublishMessageScheduler(); cfg.ConfigureEndpoints(context); }); }); var app = builder.Build(); // Enable Hangfire Dashboard app.UseHangfireDashboard("/hangfire", new DashboardOptions { Authorization = new[] { new HangfireAuthFilter() } }); app.UseHealthChecks("/health"); app.Run(); ``` -------------------------------- ### Local DynamoDB Client Configuration Source: https://masstransit.massient.com/configuration/saga-repositories/dynamodb Example of creating an `AmazonDynamoDBClient` for connecting to a local DynamoDB instance. ```csharp var dynamoDbClient = new AmazonDynamoDBClient(new AmazonDynamoDBConfig { ServiceURL = "http://localhost:4566" }); ``` -------------------------------- ### Implement a consumer with dependency injection Source: https://masstransit.massient.com/guides/message-consumer Example of a consumer class that injects a DbContext and ILogger via the constructor. ```csharp namespace MyProject.Components.Consumers; using MassTransit; using Microsoft.EntityFrameworkCore; using MyProject.Contracts; public class CreateCustomerConsumer : IConsumer { readonly DbContext _dbContext; readonly ILogger _logger; public CreateCustomerConsumer(DbContext dbContext, ILogger logger) { _dbContext = dbContext; _logger = logger; } public async Task Consume(ConsumeContext context) { _logger.LogInformation("Creating customer {CustomerName}", context.Message.CustomerName); await _dbContext.Customers.AddAsync(new Customer(context.Message.CustomerName)); await _dbContext.SaveChangesAsync(); await context.Publish(new CustomerCreated(context.Message.CustomerName)); } } ``` -------------------------------- ### Example IAM Policy for SQS and SNS Access Source: https://masstransit.massient.com/configuration/transports/amazon-sqs Provides an example IAM policy granting necessary permissions for SQS and SNS operations, including resource-specific access and broader access for listing topics. ```json { "Version": "2012-10-17", "Statement": [ { "Sid": "SqsAccess", "Effect": "Allow", "Action": [ "sqs:SetQueueAttributes", "sqs:ReceiveMessage", "sqs:CreateQueue", "sqs:DeleteMessage", "sqs:SendMessage", "sqs:GetQueueUrl", "sqs:GetQueueAttributes", "sqs:ChangeMessageVisibility", "sqs:PurgeQueue", "sqs:DeleteQueue", "sqs:TagQueue" ], "Resource": "arn:aws:sqs:*:YOUR_ACCOUNT_ID:*" }, { "Sid": "SnsAccess", "Effect": "Allow", "Action": [ "sns:GetTopicAttributes", "sns:ListSubscriptionsByTopic", "sns:GetSubscriptionAttributes", "sns:SetSubscriptionAttributes", "sns:CreateTopic", "sns:Publish", "sns:Subscribe" ], "Resource": "arn:aws:sns:*:YOUR_ACCOUNT_ID:*" }, { "Sid": "SnsListAccess", "Effect": "Allow", "Action": [ "sns:ListTopics" ], "Resource": "*" } ] } ``` -------------------------------- ### BusObserver Implementation Source: https://masstransit.massient.com/configuration/observability Implement the IBusObserver interface to monitor bus lifecycle events such as starting, stopping, and faults. ```csharp public class BusObserver : IBusObserver { /// /// Called before the bus is started, allowing observers to prepare /// public Task PreStart(IBus bus) { return Task.CompletedTask; } /// /// Called after the bus has been started successfully /// public Task PostStart(IBus bus, BusStartedContext context) { return Task.CompletedTask; } /// /// Called before the bus is stopped, allowing observers to complete any pending operations /// public Task PreStop(IBus bus) { return Task.CompletedTask; } /// /// Called after the bus has been stopped /// public Task PostStop(IBus bus, BusStoppedContext context) { return Task.CompletedTask; } /// /// Called when an unhandled exception occurs in the bus /// public Task BusFault(IBus bus, BusFaultContext context) { return Task.CompletedTask; } } ``` -------------------------------- ### Implement Custom Job Distribution Strategy Source: https://masstransit.massient.com/concepts/job-consumers Implement the `IJobDistributionStrategy` interface to define custom logic for allocating jobs to available consumer instances. This example strategy routes jobs based on customer type to specific machine types. ```csharp public class MachineTypeJobDistributionStrategy : IJobDistributionStrategy { public Task IsJobSlotAvailable(ConsumeContext context, JobTypeInfo jobTypeInfo) { object? strategy = null; jobTypeInfo.Properties?.TryGetValue("DistributionStrategy", out strategy); return strategy switch { "MachineType" => MachineType(context, jobTypeInfo), _ => DefaultJobDistributionStrategy.Instance.IsJobSlotAvailable(context, jobTypeInfo) }; } Task MachineType(ConsumeContext context, JobTypeInfo jobTypeInfo) { var customerType = context.GetHeader("CustomerType"); var machineType = customerType switch { "Premium" => "S-Class", _ => "E-Class" }; var instances = from i in jobTypeInfo.Instances join a in jobTypeInfo.ActiveJobs on i.Key equals a.InstanceAddress into ai where (ai.Count() < jobTypeInfo.ConcurrentJobLimit && string.IsNullOrEmpty(dataCenter)) || (i.Value.Properties.TryGetValue("MachineType", out var mt) && mt is string mtext && mtext == machineType) orderby ai.Count(), i.Value.Used select new { Instance = i.Value, InstanceAddress = i.Key, InstanceCount = ai.Count() }; var firstInstance = instances.FirstOrDefault(); if (firstInstance == null) return Task.FromResult(null); return Task.FromResult(new ActiveJob { JobId = context.Message.JobId, InstanceAddress = firstInstance.InstanceAddress }); } } ``` -------------------------------- ### Configure MongoDB Outbox with Default Settings Source: https://masstransit.massient.com/configuration/middleware/outbox Configures the MassTransit bus and consumer outbox using MongoDB with default settings. Ensure the MassTransit.MongoDb NuGet package is installed. ```csharp x.AddMongoDbOutbox(o => { o.QueryDelay = TimeSpan.FromSeconds(1); o.ClientFactory(provider => provider.GetRequiredService()); o.DatabaseFactory(provider => provider.GetRequiredService()); o.DuplicateDetectionWindow = TimeSpan.FromSeconds(30); o.UseBusOutbox(); }); ``` -------------------------------- ### Configure Job Type and Instance Properties Source: https://masstransit.massient.com/concepts/job-consumers Configure job type and instance properties using `JobOptions` to influence job distribution. This example sets the `DistributionStrategy` for the job type and the `MachineType` for specific instances. ```csharp x.AddConsumer(c => c.Options>(options => options .SetRetry(r => r.Interval(3, TimeSpan.FromSeconds(30))) .SetJobTimeout(TimeSpan.FromMinutes(10)) .SetConcurrentJobLimit(10) .SetJobTypeProperties(p => p.Set("DistributionStrategy", "MachineType")) .SetInstanceProperties(p => p.Set("MachineType", "S-Class"))); ``` -------------------------------- ### Order State Machine with Initial State Configuration Source: https://masstransit.massient.com/guides/saga-state-machines Configures the state machine to use the CurrentState property on the OrderState instance for tracking the instance's current state. This example uses a string for the state. ```csharp public class OrderStateMachine : MassTransitStateMachine { public OrderStateMachine() { InstanceState(x => x.CurrentState); } } ``` -------------------------------- ### Define service for state machine activity Source: https://masstransit.massient.com/guides/saga-state-machines/state-machine-activity Example service implementation that uses an injected IPublishEndpoint to publish events within the activity scope. ```csharp public interface ISomeService { Task OnOrderClosed(Guid correlationId); } public class SomeService : ISomeService { IPublishEndpoint _publishEndpoint; public SomeService(IPublishEndpoint publishEndpoint) { _publishEndpoint = publishEndpoint; } public Task OnOrderClosed(Guid correlationId) { return _publishEndpoint.Publish(new {CorrelationId = correlationId}); } } ``` -------------------------------- ### Publishing Events with Publish Source: https://masstransit.massient.com/guides/saga-state-machines/behavior Publish an event to be sent to all subscribers. This example shows publishing an OrderSubmitted event using a concrete event class. ```csharp public interface OrderSubmitted { Guid OrderId { get; } } public class OrderSubmittedEvent : OrderSubmitted { public OrderSubmittedEvent(Guid orderId) { OrderId = orderId; } public Guid OrderId { get; } } public class OrderStateMachine : MassTransitStateMachine { public OrderStateMachine() { Initially( When(SubmitOrder) .Publish(context => (OrderSubmitted)new OrderSubmittedEvent(context.Saga.CorrelationId)) .TransitionTo(Submitted)); } } ``` -------------------------------- ### Unit Test with Delayed Message Scheduler Source: https://masstransit.massient.com/guides/unit-testing This example demonstrates configuring the delayed message scheduler and using it with the in-memory transport within the MassTransit Test Harness. ```csharp [Test] public async Task A_complete_unit_test() { await using var provider = new ServiceCollection() .AddMassTransitTestHarness(x => { x.AddDelayedMessageScheduler(); x.UsingInMemory((context, cfg) => { cfg.UseDelayedMessageScheduler(); cfg.ConfigureEndpoints(context)); }); }) .BuildServiceProvider(true); var harness = await provider.StartTestHarness(); } ``` -------------------------------- ### Declare Event Implementing CorrelatedBy - MassTransit Source: https://masstransit.massient.com/guides/saga-state-machines/event Declare an event that implements the CorrelatedBy interface. The default convention automatically configures correlation by the Guid property. ```csharp public interface OrderCanceled : CorrelatedBy { } public class OrderStateMachine : MassTransitStateMachine { public OrderStateMachine() { Event(() => OrderCanceled); // not required, as it is the default convention } } ``` -------------------------------- ### Submit Command and Create Request Client Source: https://masstransit.massient.com/configuration/mediator Send a command using `mediator.Send` and create a request client from `IMediator` to send a request and get a response. Exceptions are propagated to the caller. ```csharp Guid orderId = NewId.NextGuid(); await mediator.Send(new { OrderId = orderId }); var client = mediator.CreateRequestClient(); var response = await client.GetResponse(new { OrderId = orderId }); ``` -------------------------------- ### Initialize a new MassTransit project Source: https://masstransit.massient.com/guides/message-consumer Commands to create a new class library project and add it to the solution. ```bash dotnet new classlib -o ./src/MyProject.Components dotnet sln add ./src/MyProject.Components ``` -------------------------------- ### Configure Quartz.NET with SQL Server Source: https://masstransit.massient.com/configuration/schedulers/quartz Use persistent storage with SQL Server for production environments. ```csharp services.AddQuartz(q => { q.SchedulerName = "MassTransit-Scheduler"; q.SchedulerId = "AUTO"; q.UseDefaultThreadPool(tp => { tp.MaxConcurrency = 10; }); q.UsePersistentStore(s => { s.UseProperties = true; s.RetryInterval = TimeSpan.FromSeconds(15); s.UseSqlServer(connectionString); }); }); ``` -------------------------------- ### Create a Class Library Project Source: https://masstransit.massient.com/guides/message-contract Use the .NET CLI to create a new class library project for message contracts and add it to the solution. ```bash dotnet new classlib -o ./src/MyProject.Contracts dotnet sln add ./src/MyProject.Contracts ``` -------------------------------- ### Create a Partitioner Instance Source: https://masstransit.massient.com/configuration/middleware/partitioner Create a `Partitioner` instance by specifying the number of partitions and a hash generator. The `Murmur3UnsafeHashGenerator` is recommended for distributing partition keys. ```csharp var partition = new Partitioner(16, new Murmur3UnsafeHashGenerator()); ``` -------------------------------- ### Add or Update Recurring Job with Start and End Dates Source: https://masstransit.massient.com/concepts/job-consumers Schedule recurring jobs within a specific time frame by providing start and end dates. The job will run at the first opportunity after the start date and will not run after the end date. ```csharp public async Task ConfigureRecurringJobs(IPublishEndpoint endpoint) { await endpoint.AddOrUpdateRecurringJob("RoutineMaintenance", new RoutineMaintenanceCommand(), x => { x.Start = new DateTimeOffset(2024, 1, 1, 0, 0, 0, TimeSpan.Zero); x.End = new DateTimeOffset(2025, 1, 1, 0, 0, 0, TimeSpan.Zero); x.Every(minutes: 30); }); } ``` -------------------------------- ### Message URN Examples Source: https://masstransit.massient.com/configuration/serialization Examples of URN formats used by MassTransit to identify message types, including nested classes. ```text urn:message:MyProject.Messages:UpdateAccount urn:message:MyProject.Messages.Events:AccountUpdated urn:message:MyProject:ChangeAccount urn:message:MyProject.AccountService:MyService+AccountUpdatedEvent ``` -------------------------------- ### Configure Quartz Clustering Source: https://masstransit.massient.com/configuration/schedulers/quartz Set up persistent storage and clustering options for high availability in Quartz.NET. ```csharp services.AddQuartz(q => { q.SchedulerName = "MassTransit-Scheduler"; q.SchedulerId = "AUTO"; q.UseDefaultThreadPool(tp => { tp.MaxConcurrency = 10; }); q.UsePersistentStore(s => { s.UseProperties = true; s.PerformSchemaValidation = true; s.RetryInterval = TimeSpan.FromSeconds(15); s.UseSqlServer(connectionString); s.UseClustering(c => { c.CheckinMisfireThreshold = TimeSpan.FromSeconds(20); c.CheckinInterval = TimeSpan.FromSeconds(10); }); }); }); ``` -------------------------------- ### Generate a NewId and Guid Source: https://masstransit.massient.com/reference/newid Use NewId.Next() to generate a NewId object or NewId.NextGuid() to generate a Guid. These methods provide sequential unique identifiers. ```csharp NewId newId = NewId.Next(); ``` ```csharp Guid guid = NewId.NextGuid(); ``` -------------------------------- ### Execute Topology Deployment Source: https://masstransit.massient.com/configuration/topology Use IBusControl.DeployAsync to apply the configured topology to the broker. ```csharp var busControl = provider.GetRequiredService(); try { using var source = new CancellationTokenSource(TimeSpan.FromMinutes(2)); await busControl.DeployAsync(source.Token); Console.WriteLine("Topology Deployed"); } catch (Exception ex) { Console.WriteLine("Failed to deploy topology: {0}", ex); } ``` -------------------------------- ### Create Kafka Topic Producer Dynamically Source: https://masstransit.massient.com/configuration/transports/kafka Demonstrates how to dynamically create a topic producer using ITopicProducerProvider. This allows for on-the-fly producer instantiation for specific topics. ```csharp var producerProvider = provider.GetRequiredService(); var producer = producerProvider.GetProducer(new Uri($"topic:topic-name")); await producer.Produce(new { TopicName = value }); ``` -------------------------------- ### MassTransit Health Check Status Example Source: https://masstransit.massient.com/configuration An example JSON output illustrating the health status of MassTransit, including endpoint status, durations, and tags. This output is typically returned by the health check endpoints. ```json { "status": "Healthy", "totalDuration": "00:00:00.2134026", "entries": { "masstransit-bus": { "data": { "Endpoints": { "rabbitmq://localhost/dev-local/SubmitOrder": { "status": "Healthy", "description": "ready" } } }, "description": "Ready", "duration": "00:00:00.1853530", "status": "Healthy", "tags": [ "ready", "masstransit" ] } } } ``` -------------------------------- ### Run Mvc Sample Source: https://masstransit.massient.com/configuration/integrations/signalr Commands to run the MassTransit SignalR Mvc sample on two different ports to simulate scaleout. This allows testing inter-client communication. ```bash > cd (your cloned Sample-SignalR)\src\SampleSignalR.Mvc > dotnet run --launch-profile sample1 > dotnet run --launch-profile sample2 ``` -------------------------------- ### Example Telemetry Report Source: https://masstransit.massient.com/reference/usage-telemetry A sample JSON payload representing the anonymous data collected by MassTransit. ```json { "id": "bd740008-ebb8-e450-a00a-08dd60e7bc9c", "bus": [ { "name": "IBus", "created": "2025-03-11T16:57:37.4587070-05:00", "started": "2025-03-11T16:57:37.9216500-05:00", "endpoints": [ { "name": "odd-job", "type": "RabbitMQ", "consumer_count": 5, "prefetch_count": 64, "job_consumer_count": 1 }, { "name": "odd-job-completed", "type": "RabbitMQ", "consumer_count": 1, "prefetch_count": 1, "concurrent_message_limit": 1 }, { "name": "job-type", "type": "RabbitMQ", "prefetch_count": 64, "concurrent_message_limit": 16, "saga_state_machine_count": 1 }, { "name": "job", "type": "RabbitMQ", "prefetch_count": 64, "concurrent_message_limit": 16, "saga_state_machine_count": 1 }, { "name": "job-attempt", "type": "RabbitMQ", "prefetch_count": 64, "concurrent_message_limit": 16, "saga_state_machine_count": 1 } ], "configured": "2025-03-11T16:57:37.8701060-05:00" } ], "host": { "commit_hash": "c0977e09482f7f5e3585c9a59e67941a89fd2963", "time_zone_info": "(UTC-06:00) Central Time (Chicago)", "framework_version": "9.0.0", "mass_transit_version": "1.0.0.0", "operating_system_version": "Unix 14.7.2" }, "created": "2025-03-12T16:57:37.4572470-05:00" } ``` -------------------------------- ### Sending Commands with Send Source: https://masstransit.massient.com/guides/saga-state-machines/behavior Send a command to a specific endpoint. This example sends an UpdateAccountHistoryCommand to the AccountServiceAddress. ```csharp public interface UpdateAccountHistory { Guid OrderId { get; } } public class UpdateAccountHistoryCommand : UpdateAccountHistory { public UpdateAccountHistoryCommand(Guid orderId) { OrderId = orderId; } public Guid OrderId { get; } } public class OrderStateMachine : MassTransitStateMachine { public OrderStateMachine(OrderStateMachineSettings settings) { Initially( When(SubmitOrder) .Send(settings.AccountServiceAddress, context => new UpdateAccountHistoryCommand(context.Saga.CorrelationId)) .TransitionTo(Submitted)); } } ``` -------------------------------- ### Application Configuration Source: https://masstransit.massient.com/configuration/schedulers/quartz Connection string settings for Quartz and RabbitMQ in appsettings.json. ```json { "ConnectionStrings": { "quartz": "Server=.;Database=Quartz;Trusted_Connection=True;TrustServerCertificate=true", "RabbitMq": "rabbitmq://localhost:5672" } } ``` -------------------------------- ### Define NServiceBus Message Contracts Source: https://masstransit.massient.com/configuration/integrations/nsb Example message contracts implementing IEvent for NServiceBus communication. ```csharp public class ClockUpdated : IEvent { public DateTime CurrentTime { get; set; } } public class ClockSynchronized : IEvent { public string Host {get;set;} } ``` -------------------------------- ### Configure Cosmos DB emulator Source: https://masstransit.massient.com/configuration/saga-repositories/azure-cosmos Use the ConfigureEmulator method to point the repository to a local Cosmos DB emulator instance. ```csharp container.AddMassTransit(cfg => { cfg.AddSagaStateMachine() .CosmosRepository(r => { r.ConfigureEmulator(); r.DatabaseId = "test"; }); }); ``` -------------------------------- ### Configure OpenTelemetry Resource and Tracer Provider Source: https://masstransit.massient.com/configuration/observability Sets up the OpenTelemetry resource with service details and builds a tracer provider that includes the MassTransit meter and a console exporter. This is typically done during application startup. ```csharp void ConfigureResource(ResourceBuilder r) { r.AddService("Service Name", serviceVersion: "Version", serviceInstanceId: Environment.MachineName); } Sdk.CreateTracerProviderBuilder() .ConfigureResource(ConfigureResource) .AddMeter(InstrumentationOptions.MeterName) // MassTransit Meter .AddConsoleExporter() // Any OTEL suportable exporter can be used here .Build() ``` -------------------------------- ### Configure RabbitMQ Host Source: https://masstransit.massient.com/configuration/transports/rabbitmq Minimal configuration for connecting to a local RabbitMQ instance using default credentials. ```csharp namespace RabbitMqConsoleListener; using System.Threading.Tasks; using MassTransit; using Microsoft.Extensions.Hosting; public static class Program { public static async Task Main(string[] args) { await Host.CreateDefaultBuilder(args) .ConfigureServices(services => { services.AddMassTransit(x => { x.UsingRabbitMq((context, cfg) => { cfg.Host("localhost", "/", h => { h.Username("guest"); h.Password("guest"); }); }); }); }) .Build() .RunAsync(); } } ``` -------------------------------- ### Get Response Task Source: https://masstransit.massient.com/reference/irequestclient Methods to initiate a request and return a task for a specific response type. ```csharp Task> GetResponse(TRequest message, CancellationToken cancellationToken, RequestTimeout timeout) ``` ```csharp Task> GetResponse(TRequest message, RequestPipeConfiguratorCallback callback, CancellationToken cancellationToken, RequestTimeout timeout) ``` ```csharp Task> GetResponse(object values, CancellationToken cancellationToken, RequestTimeout timeout) ``` -------------------------------- ### Configure a single bus instance Source: https://masstransit.massient.com/configuration/multibus Standard configuration for a single bus using RabbitMQ and automatic endpoint registration. ```csharp services.AddMassTransit(x => { x.AddConsumer(); x.AddRequestClient(); x.UsingRabbitMq((context, cfg) => { cfg.ConfigureEndpoints(context); }); }); ``` -------------------------------- ### Example MassTransit JSON Message Envelope Source: https://masstransit.massient.com/configuration/serialization Represents the standard structure of a message encapsulated by MassTransit for serialization. ```json { "messageId": "181c0000-6393-3630-36a4-08daf4e7c6da", "requestId": "ef375b18-69ee-4a9e-b5ec-44ee1177a27e", "correlationId": null, "conversationId": null, "initiatorId": null, "sourceAddress": "rabbitmq://localhost/source", "destinationAddress": "rabbitmq://localhost/destination", "responseAddress": "rabbitmq://localhost/response", "faultAddress": "rabbitmq://localhost/fault", "messageType": [ "urn:message:Company.Project:SubmitOrder" ], "message": { "orderId": "181c0000-6393-3630-36a4-08daf4e7c6da", "timestamp": "2023-01-12T21:55:53.714Z" }, "expirationTime": null, "sentTime": "2023-01-12T21:55:53.715882Z", "headers": { "Application-Header": "SomeValue" }, "host": { "machineName": "MyComputer", "processName": "dotnet", "processId": 427, "assembly": "TestProject", "assemblyVersion": "2.11.1.93", "frameworkVersion": "6.0.7", "massTransitVersion": "8.0.10.0", "operatingSystemVersion": "Unix 12.6.2" } } ``` -------------------------------- ### Consume Fault Messages Source: https://masstransit.massient.com/concepts/exceptions Example of a consumer designed to process Fault messages for monitoring or operational tasks. ```csharp public class DashboardFaultConsumer : IConsumer> { public async Task Consume(ConsumeContext> context) { // update the dashboard } } ``` -------------------------------- ### Get Send Endpoint and Send Message Source: https://masstransit.massient.com/concepts/producers Demonstrates obtaining an ISendEndpoint from an ISendEndpointProvider and sending a message asynchronously. ```csharp public record SubmitOrder { public string OrderId { get; init; } } public async Task SendOrder(ISendEndpointProvider sendEndpointProvider) { var endpoint = await sendEndpointProvider.GetSendEndpoint(_serviceAddress); await endpoint.Send(new SubmitOrder { OrderId = "123" }); } ``` -------------------------------- ### Example Raw JSON Message Source: https://masstransit.massient.com/configuration/serialization Represents a message payload when using a serializer that does not wrap the message in a MassTransit envelope. ```json { "orderId": "181c0000-6393-3630-36a4-08daf4e7c6da", "timestamp": "2023-01-12T21:55:53.714Z" } ``` -------------------------------- ### Using IClientFactory in a Worker Method Source: https://masstransit.massient.com/concepts/requests Example of using IClientFactory to create a request client outside of a scoped context. ```csharp public async Task WorkerMethod(IServiceProvider provider) { var clientFactory = provider.GetRequiredService(); var serviceAddress = new Uri("exchange:check-order-status"); var client = clientFactory.CreateRequestClient(serviceAddress); var response = await client.GetResponse(new { OrderId = id}); } ``` -------------------------------- ### Create a configuration extension method Source: https://masstransit.massient.com/guides/middleware Provides a fluent API for adding the filter specification to a pipe configurator. ```csharp public static class ExampleMiddlewareConfiguratorExtensions { public static void UseExceptionLogger(this IPipeConfigurator configurator) where T : class, PipeContext { configurator.AddPipeSpecification(new ExceptionLoggerSpecification()); } } ``` -------------------------------- ### Configure Serilog in Program.cs Source: https://masstransit.massient.com/configuration/logging Initializes the global Serilog logger and integrates it with the MassTransit host and service bus configuration. ```csharp using Serilog; using Serilog.Events; Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() .MinimumLevel.Override("MassTransit", LogEventLevel.Information) .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) .MinimumLevel.Override("Microsoft.Hosting", LogEventLevel.Information) .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Fatal) .MinimumLevel.Override("Microsoft.EntityFrameworkCore.Database.Command", LogEventLevel.Fatal) .Enrich.FromLogContext() .WriteTo.Console() .CreateLogger(); var builder = WebApplication.CreateBuilder(args); builder.Host.UseSerilog(); builder.Services.AddMassTransit(x => { x.AddServiceBusMessageScheduler(); x.UsingAzureServiceBus((context, cfg) => { cfg.Host(serviceBusConnectionString); cfg.UseServiceBusMessageScheduler(); cfg.ConfigureEndpoints(context); }); }); ``` -------------------------------- ### Using IScopedClientFactory in an ASP.NET Controller Source: https://masstransit.massient.com/concepts/requests Example of using IScopedClientFactory to dynamically resolve a request client based on a tenant ID. ```csharp [HttpGet] public async Task HandleGet(string tenantId, int id, [FromServices] IScopedClientFactory clientFactory) { var serviceAddress = new Uri($"exchange:check-order-status-{tenantId}"); var client = clientFactory.CreateRequestClient(serviceAddress); var response = await client.GetResponse(new { OrderId = id}); return Ok(); } ``` -------------------------------- ### Declare Event with Correlation - MassTransit Source: https://masstransit.massient.com/guides/saga-state-machines/event Declare an event with explicit correlation by ID. This is useful when the event message does not implement CorrelatedBy. ```csharp public interface SubmitOrder { Guid OrderId { get; } } public class OrderStateMachine : MassTransitStateMachine { public OrderStateMachine() { Event(() => SubmitOrder, x => x.CorrelateById(context => context.Message.OrderId)); } public Event SubmitOrder { get; private set; } } ``` -------------------------------- ### Run Entity Framework Migrations for Multiple DbContexts Source: https://masstransit.massient.com/configuration/saga-repositories/entity-framework Commands to generate and apply migrations when multiple DbContext types are present. ```bash dotnet ef migrations add InitialCreate -c JobServiceSagaDbContext ``` ```bash dotnet ef database update -c JobServiceSagaDbContext ``` -------------------------------- ### Configure Topic Creation Options Source: https://masstransit.massient.com/configuration/transports/azure-service-bus Configures options for when an Azure Service Bus topic is created, such as enabling partitioning. This is done during bus creation. ```csharp cfg.Publish(x => { x.EnablePartitioning = true; }); ``` -------------------------------- ### Async Message Factory Examples Source: https://masstransit.massient.com/guides/saga-state-machines/request Use an async message factory when the request message needs data from an asynchronous method or when using a message initializer. ```csharp .Request(ValidateOrder, async context => new ValidateOrder(context.Saga.CorrelationId)) ``` ```csharp .Request(ValidateOrder, context => context.Saga.ServiceAddress, async context => new ValidateOrder(context.Saga.CorrelationId)) ``` ```csharp .Request(ValidateOrder, async context => { await Task.Delay(1); // some async method return new ValidateOrder(); }); ``` -------------------------------- ### Scoped Concrete Consume Filter Source: https://masstransit.massient.com/guides/middleware Example of a concrete scoped consume filter. This filter is defined for a specific message type and can be resolved from the container for each message. ```csharp public class MyMessageConsumeFilter : IFilter> ``` -------------------------------- ### Build a Routing Slip Source: https://masstransit.massient.com/guides/routing-slips/monitor-using-a-saga Initializes a Routing Slip builder and adds activities and variables to the execution plan. ```csharp var builder = new RoutingSlipBuilder(NewId.NextGuid()); // add your activities as normal builder.AddActivity("DownloadImage", new Uri("queue:download-image_execute?bind=false"), new { ImageUri = new Uri("https://images.google.com/someImage.jpg") }); builder.AddActivity("FilterImage", new Uri("queue:filter-image_execute?bind=false")); builder.AddVariable("WorkPath", @"\dfs\work"); ``` -------------------------------- ### Configure DbContext with Outbox Entities Source: https://masstransit.massient.com/configuration/middleware/outbox Extends DbContext to include the necessary tables for the Entity Framework outbox. This setup is required for the transactional outbox to function. ```csharp public class RegistrationDbContext : DbContext { public RegistrationDbContext(DbContextOptions options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.AddInboxStateEntity(); modelBuilder.AddOutboxMessageEntity(); modelBuilder.AddOutboxStateEntity(); } } ``` -------------------------------- ### Use Optimistic Concurrency Attribute Source: https://masstransit.massient.com/configuration/saga-repositories/marten Applies the UseOptimisticConcurrency attribute to the saga state class to enable optimistic concurrency. This is an alternative to configuring it in the repository setup. ```csharp [UseOptimisticConcurrency] public class OrderState : SagaStateMachineInstance { public Guid CorrelationId { get; set; } // ... } ``` -------------------------------- ### Configure MassTransit Host Options Source: https://masstransit.massient.com/configuration Uses the Options pattern to configure MassTransitHostOptions for controlling bus startup and shutdown behavior. ```csharp services.AddOptions() .Configure(options => { }); ``` -------------------------------- ### Configure Mediator with Consumers Source: https://masstransit.massient.com/configuration/mediator Configure the MassTransit Mediator by adding consumers using the `AddMediator` extension method on `IServiceCollection`. This setup is for in-process message handling. ```csharp using MassTransit; using MassTransit.Mediator services.AddMediator(cfg => { cfg.AddConsumer(); cfg.AddConsumer(); }); ``` -------------------------------- ### Implement IPublishObserver Source: https://masstransit.massient.com/configuration/observability Define a class implementing IPublishObserver to hook into pre-publish, post-publish, and fault events. ```csharp public class PublishObserver : IPublishObserver { /// /// Called right before the message is published to the transport (exchange/topic). /// All headers are configured and the message is serialized. /// Note: This is for publish operations (IPublishEndpoint), not for sends. /// Use both PublishObserver and SendObserver to observe all outbound messages. /// public Task PrePublish(PublishContext context) where T : class { return Task.CompletedTask; } /// /// Called after the message is published and acknowledged by the broker. /// The message is now available to all subscribers. /// public Task PostPublish(PublishContext context) where T : class { return Task.CompletedTask; } /// /// Called if an exception occurs while publishing the message. /// This includes serialization errors, routing failures, or transport errors. /// public Task PublishFault(PublishContext context, Exception exception) where T : class { return Task.CompletedTask; } } ``` -------------------------------- ### Add project reference Source: https://masstransit.massient.com/guides/message-consumer Command to reference the contracts project from the components project. ```bash dotnet reference add ./src/MyProject.Contracts --project ./src/MyProject.Components ``` -------------------------------- ### Run Console Sample Source: https://masstransit.massient.com/configuration/integrations/signalr Command to run the MassTransit SignalR console sample application. This service can broadcast messages to all connected SignalR clients. ```bash > cd (your cloned Sample-SignalR)\src\SampleSignalR.Service > dotnet run ``` -------------------------------- ### Configure MessageData with InMemory Repository Source: https://masstransit.massient.com/configuration/message-data Configure the MassTransit bus to use message data by specifying the message data repository. This example uses an in-memory repository. ```csharp services.AddMassTransit(x => { x.UsingInMemory((context, cfg) => { cfg.UseMessageData(x => x.InMemory()); cfg.ConfigureEndpoints(context); }); }); ``` -------------------------------- ### Schedule a Job with a Specific Start Time Source: https://masstransit.massient.com/concepts/job-consumers Schedule a job to run at a specific time in the future using the ScheduleJob method, providing a DateTimeOffset and the job message. ```csharp [HttpPost("{path}")] public async Task SubmitJob(string path, [FromServices] IRequestClient> client) { await client.ScheduleJob(DateTimeOffset.Now.AddMinutes(15), new ConvertVideo { Path = path }); return Ok(new { jobId, path }); } ```