Create a Message Consumer
A message consumer, the most common consumer type, is a class that consumes one or more message types. For each message type, the class implements
the IConsumer<TMessage> interface that has a single Consume method.
MassTransit also supports conventional consumers using the [Consumer] attribute. Conventional consumers still implement the IConsumer marker interface, but
message types are identified from public Consume methods instead of IConsumer<TMessage> interfaces.
Creating a message consumer
Section titled “Creating a message consumer”To create a message consumer:
Create a new project
Section titled “Create a new project”Create a new project (or use an existing project) using the class library template. If you’re using an existing project, skip this step.
dotnet new classlib -o ./src/MyProject.Componentsdotnet sln add ./src/MyProject.ComponentsReference the Contracts project
Section titled “Reference the Contracts project”Add a reference to the message contract project using your IDE, or by running the following command from the command line.
dotnet reference add ./src/MyProject.Contracts --project ./src/MyProject.ComponentsCreate a consumer class
Section titled “Create a consumer class”Create a new class in the MyProject.Components project. To keep components organized, create a new folder for consumers.
namespace MyProject.Components.Consumers;
using MassTransit;using MyProject.Contracts;
public class CreateCustomerConsumer : IConsumer<CreateCustomer>{ public async Task Consume(ConsumeContext<CreateCustomer> context) { // Handle the message }}Inject constructor dependencies
Section titled “Inject constructor dependencies”Message consumers can have dependencies injected into their constructors. For example, if the consumer needs to access a database, inject the database context
into the consumer’s constructor. You may also want to inject other services, such as an ILogger<T> instance.
namespace MyProject.Components.Consumers;
using MassTransit;using Microsoft.EntityFrameworkCore;using MyProject.Contracts;
public class CreateCustomerConsumer : IConsumer<CreateCustomer>{ readonly DbContext _dbContext; readonly ILogger<CreateCustomerConsumer> _logger;
public CreateCustomerConsumer(DbContext dbContext, ILogger<CreateCustomerConsumer> logger) { _dbContext = dbContext; _logger = logger; }
public async Task Consume(ConsumeContext<CreateCustomer> 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)); }}Create a conventional consumer
Section titled “Create a conventional consumer”New in v9.2.1
If you prefer method-based injection on the Consume method, use [Consumer] with the IConsumer marker interface.
namespace MyProject.Components.Consumers;
using MassTransit;using MyProject.Contracts;
[Consumer]public class CreateCustomerConsumer : IConsumer{ public async Task Consume(CreateCustomer message, DbContext dbContext, IPublishEndpoint publishEndpoint, ILogger<CreateCustomerConsumer> logger, CancellationToken cancellationToken) { logger.LogInformation("Creating customer {CustomerName}", message.CustomerName);
await dbContext.Customers.AddAsync(new Customer(message.CustomerName)); await dbContext.SaveChangesAsync();
await publishEndpoint.Publish(new CustomerCreated(message.CustomerName)); }}The first parameter can be either CreateCustomer or ConsumeContext<CreateCustomer>. Any additional parameters are resolved from the consume scope, including
CancellationToken, IPublishEndpoint, ISendEndpointProvider, and ConsumeContext.
Next steps
Section titled “Next steps”Once you’ve created a message consumer, you can learn about testing a consumer to verify that it’s working correctly.