RepletoryLib.Messaging.Abstractions 1.0.0

dotnet add package RepletoryLib.Messaging.Abstractions --version 1.0.0
                    
NuGet\Install-Package RepletoryLib.Messaging.Abstractions -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="RepletoryLib.Messaging.Abstractions" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RepletoryLib.Messaging.Abstractions" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="RepletoryLib.Messaging.Abstractions" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add RepletoryLib.Messaging.Abstractions --version 1.0.0
                    
#r "nuget: RepletoryLib.Messaging.Abstractions, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package RepletoryLib.Messaging.Abstractions@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=RepletoryLib.Messaging.Abstractions&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=RepletoryLib.Messaging.Abstractions&version=1.0.0
                    
Install as a Cake Tool

RepletoryLib.Messaging.Abstractions

Messaging abstractions and interfaces for the RepletoryLib ecosystem.

Part of the RepletoryLib ecosystem -- standalone, reusable .NET 10 libraries with zero business logic.

NuGet .NET 10 License: MIT


Overview

RepletoryLib.Messaging.Abstractions defines the contracts for asynchronous messaging in the RepletoryLib ecosystem. It provides interfaces for publishing events and commands, consuming messages, and an event bus abstraction for both pub/sub and point-to-point messaging patterns.

By programming against these interfaces, your application code stays decoupled from the message transport -- you can swap between RabbitMQ, in-memory messaging, or any future transport without changing business logic.

This package contains interfaces only -- no implementations. Choose an implementation package based on your needs.

Choosing an Implementation

Package Technology Best For
RepletoryLib.Messaging.RabbitMQ MassTransit + RabbitMQ Production distributed messaging
RepletoryLib.Messaging.Outbox EF Core transactional outbox Reliable messaging with at-least-once delivery

Key Features

  • IMessagePublisher -- Publish messages to default or named exchanges
  • IMessageConsumer<T> -- Consume typed messages with rich context (headers, correlation ID, timestamp)
  • IEventBus -- Higher-level abstraction for publishing events and sending commands to destinations
  • ConsumeContext<T> -- Metadata-rich envelope for consumed messages

Installation

dotnet add package RepletoryLib.Messaging.Abstractions

Or add to your .csproj:

<PackageReference Include="RepletoryLib.Messaging.Abstractions" Version="1.0.0" />

Note: RepletoryLib packages are published to a local BaGet feed. See the main repository README for feed configuration.

Dependencies

Package Type
RepletoryLib.Common RepletoryLib

Usage Examples

Publishing Events

Use IMessagePublisher to publish events to the default exchange or a named exchange:

using RepletoryLib.Messaging.Abstractions.Interfaces;

public class OrderService
{
    private readonly IMessagePublisher _publisher;

    public OrderService(IMessagePublisher publisher) => _publisher = publisher;

    public async Task CreateOrderAsync(Order order)
    {
        // ... save order to database ...

        // Publish to default exchange
        await _publisher.PublishAsync(new OrderCreatedEvent
        {
            OrderId = order.Id,
            CustomerId = order.CustomerId,
            Total = order.Total,
            CreatedAt = DateTime.UtcNow
        });

        // Publish to a specific exchange
        await _publisher.PublishAsync(new OrderNotification
        {
            OrderId = order.Id,
            Message = "New order placed"
        }, "notifications");
    }
}

Consuming Messages

Implement IMessageConsumer<T> to handle incoming messages:

using RepletoryLib.Messaging.Abstractions.Interfaces;
using RepletoryLib.Messaging.Abstractions.Models;

public class OrderCreatedConsumer : IMessageConsumer<OrderCreatedEvent>
{
    private readonly IEmailService _email;
    private readonly ILogger<OrderCreatedConsumer> _logger;

    public OrderCreatedConsumer(IEmailService email, ILogger<OrderCreatedConsumer> logger)
    {
        _email = email;
        _logger = logger;
    }

    public async Task ConsumeAsync(ConsumeContext<OrderCreatedEvent> context,
        CancellationToken cancellationToken = default)
    {
        _logger.LogInformation(
            "Processing order {OrderId}, CorrelationId: {CorrelationId}",
            context.Message.OrderId,
            context.CorrelationId);

        await _email.SendOrderConfirmationAsync(
            context.Message.CustomerId,
            context.Message.OrderId);
    }
}

Using the Event Bus

IEventBus provides a higher-level API with separate methods for events (pub/sub) and commands (point-to-point):

using RepletoryLib.Messaging.Abstractions.Interfaces;

public class CheckoutService
{
    private readonly IEventBus _bus;

    public CheckoutService(IEventBus bus) => _bus = bus;

    public async Task CompleteCheckoutAsync(Guid orderId)
    {
        // Publish event (fan-out to all subscribers)
        await _bus.PublishAsync(new CheckoutCompletedEvent { OrderId = orderId });

        // Send command to a specific destination (point-to-point)
        await _bus.SendAsync(new ProcessPaymentCommand
        {
            OrderId = orderId,
            Amount = 1500.00m
        }, "payment-queue");
    }
}

Defining Message Contracts

Define messages as simple classes:

// Events represent something that happened
public class OrderCreatedEvent
{
    public Guid OrderId { get; set; }
    public Guid CustomerId { get; set; }
    public decimal Total { get; set; }
    public DateTime CreatedAt { get; set; }
}

// Commands represent something that should happen
public class ProcessPaymentCommand
{
    public Guid OrderId { get; set; }
    public decimal Amount { get; set; }
}

API Reference

IMessagePublisher

public interface IMessagePublisher
{
    Task PublishAsync<T>(T message, CancellationToken cancellationToken = default) where T : class;
    Task PublishAsync<T>(T message, string exchange, CancellationToken cancellationToken = default) where T : class;
}
Method Description
PublishAsync<T>(message) Publishes a message to the default exchange
PublishAsync<T>(message, exchange) Publishes a message to a named exchange

IMessageConsumer<T>

public interface IMessageConsumer<in T> where T : class
{
    Task ConsumeAsync(ConsumeContext<T> context, CancellationToken cancellationToken = default);
}

IEventBus

public interface IEventBus
{
    Task PublishAsync<T>(T @event, CancellationToken cancellationToken = default) where T : class;
    Task SendAsync<T>(T command, string destination, CancellationToken cancellationToken = default) where T : class;
}
Method Description
PublishAsync<T> Publishes an event (fan-out to all subscribers)
SendAsync<T> Sends a command to a specific destination (point-to-point)

ConsumeContext<T>

public class ConsumeContext<T> where T : class
{
    public required T Message { get; init; }
    public required string MessageId { get; init; }
    public string? CorrelationId { get; init; }
    public required DateTime Timestamp { get; init; }
    public required IDictionary<string, string> Headers { get; init; }
}
Property Type Description
Message T The deserialized message payload
MessageId string Unique identifier for this message
CorrelationId string? Correlation ID for distributed tracing
Timestamp DateTime When the message was published
Headers IDictionary<string, string> Transport-level headers

MessagingOptions

public class MessagingOptions
{
    public const string SectionName = "Messaging";

    public string Host { get; set; } = "localhost";
    public string VirtualHost { get; set; } = "/";
    public string Username { get; set; } = "guest";
    public string Password { get; set; } = "guest";
    public int Port { get; set; } = 5672;
    public int RetryCount { get; set; } = 3;
    public int RetryIntervalSeconds { get; set; } = 5;
}

Integration with Other RepletoryLib Packages

Package Relationship
RepletoryLib.Common Direct dependency -- provides base types
RepletoryLib.Messaging.RabbitMQ MassTransit-based implementation of all messaging interfaces
RepletoryLib.Messaging.Outbox Transactional outbox for reliable message publishing with EF Core
RepletoryLib.Testing Provides MockMessagePublisher for unit testing
RepletoryLib.Logging Correlate messages using correlation IDs from the logging pipeline

Testing

Use MockMessagePublisher from RepletoryLib.Testing to verify published messages:

using RepletoryLib.Testing;

public class OrderServiceTests : TestBase
{
    [Fact]
    public async Task CreateOrder_publishes_event()
    {
        Setup();
        Services.AddTransient<OrderService>();
        var provider = BuildServiceProvider();
        var service = provider.GetRequiredService<OrderService>();

        await service.CreateOrderAsync(new Order { Id = Guid.NewGuid(), Total = 500m });

        MockPublisher.GetPublished<OrderCreatedEvent>().Should().HaveCount(1);
        MockPublisher.GetPublished<OrderCreatedEvent>().First().Total.Should().Be(500m);
    }

    [Fact]
    public async Task CreateOrder_publishes_notification_to_exchange()
    {
        Setup();
        Services.AddTransient<OrderService>();
        var provider = BuildServiceProvider();
        var service = provider.GetRequiredService<OrderService>();

        await service.CreateOrderAsync(new Order { Id = Guid.NewGuid() });

        MockPublisher.GetPublished<OrderNotification>("notifications").Should().HaveCount(1);
    }
}

Troubleshooting

Issue Solution
IMessagePublisher not registered in DI Install and register an implementation package (Messaging.RabbitMQ)
Consumer not receiving messages Ensure the consumer is registered in AddRepletoryRabbitMQ configuration
Messages lost during database save Use RepletoryLib.Messaging.Outbox for transactional outbox pattern

License

This project is licensed under the MIT License.

Copyright (c) 2024-2026 Repletory.


For complete documentation, infrastructure setup, and configuration reference, see the RepletoryLib main repository.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on RepletoryLib.Messaging.Abstractions:

Package Downloads
RepletoryLib.Messaging.RabbitMQ

RabbitMQ messaging via MassTransit for RepletoryLib

RepletoryLib.Testing

Test helpers, mocks, and base classes for RepletoryLib

RepletoryLib.Messaging.Outbox

Transactional outbox pattern for reliable messaging in RepletoryLib

RepletoryLib.Ai.Moderation

Multi-stage AI content moderation pipeline with keyword, provider, and semantic analysis stages for RepletoryLib

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 90 3/2/2026