SamSoft.ModularMonolith.Messaging 1.0.3

dotnet add package SamSoft.ModularMonolith.Messaging --version 1.0.3
                    
NuGet\Install-Package SamSoft.ModularMonolith.Messaging -Version 1.0.3
                    
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="SamSoft.ModularMonolith.Messaging" Version="1.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SamSoft.ModularMonolith.Messaging" Version="1.0.3" />
                    
Directory.Packages.props
<PackageReference Include="SamSoft.ModularMonolith.Messaging" />
                    
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 SamSoft.ModularMonolith.Messaging --version 1.0.3
                    
#r "nuget: SamSoft.ModularMonolith.Messaging, 1.0.3"
                    
#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 SamSoft.ModularMonolith.Messaging@1.0.3
                    
#: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=SamSoft.ModularMonolith.Messaging&version=1.0.3
                    
Install as a Cake Addin
#tool nuget:?package=SamSoft.ModularMonolith.Messaging&version=1.0.3
                    
Install as a Cake Tool

ModularMonolith.Messaging

A robust, scalable messaging infrastructure designed for modular monolithic applications.

Overview

ModularMonolith.Messaging provides a lightweight yet powerful messaging system that enables communication between modules in a modular monolith architecture. It offers the benefits of service isolation while avoiding the complexity and overhead of a full microservices implementation.

Features

  • Decoupled Module Communication: Enables modules to communicate without direct dependencies
  • Type-Safe Message Handling: Strong typing for message contracts and handlers
  • In-Process Messaging: High-performance in-memory message passing
  • Support for Integration Events: Facilitate integration with external systems
  • Extensible Architecture: Designed for easy addition of new message types and handlers

Installation

Install the package via NuGet:

dotnet add package ModularMonolith.Messaging

Basic Usage

1. Define a Message (Contract Project)


public class OrderCreatedEvent
{
    public Guid OrderId { get; set; }
    public string CustomerName { get; set; } = string.Empty;
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    public decimal TotalAmount { get; set; }
}

2. Modules

  • Cart Module: Create Cart.
  • Order Module: Create Order.
  • Customer Module: Customer Orders.
  • Payment Module: Customer Payment Data.
  • Contract: Has Contracts (Shared Project).
  • WebApi: Web Api Project.

3. In Every Modules Has This Static Class


internal static class AssemblyReference
{
    public static readonly Assembly Assembly = typeof(AssemblyReference).Assembly;
    public static readonly string ModuleName = typeof(AssemblyReference).Assembly.GetName().Name!;
}

Use It To Get Assembly And ModuleName

4. In Cart Module


public interface IOrderService
{
    Task<Guid> CreateOrder(string customerName, decimal totalAmount);
}


internal sealed class OrderService : IOrderService
{
    private readonly IBus _bus;
    public OrderService(IBus bus) => _bus = bus;
    public async Task<Guid> CreateOrder(string customerName, decimal totalAmount)
    {
        var orderId = Guid.NewGuid();
        var orderCreatedEvent = new OrderCreatedEvent
        {
            OrderId = orderId,
            CreatedAt = DateTime.UtcNow,
            CustomerName = customerName,
            TotalAmount = totalAmount
        };

        // Add Any Another Logic

        await _bus.SendAsync(orderCreatedEvent);
        return orderId;
    }
}

  • OrderService Will sent OrderCreatedEvent to all modules that are interested in this Event throw SendAsync Method.

5. Adding Consumer To Modules


internal class OrderCreatedEventConsumer(ILogger<OrderCreatedEvent> logger) : IConsumer<OrderCreatedEvent>
{
    private readonly ILogger<OrderCreatedEvent> _logger = logger;

    public Task ConsumeAsync(OrderCreatedEvent message, CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "Starting Message {@RequestName} Consumer On {@CurrentDateTime} on {Module}",
            typeof(OrderCreatedEvent).Name, DateTime.UtcNow, AssemblyReference.ModuleName);
        //Console.WriteLine($"{AssemblyReference.ModuleName} Received: From Customer: {message.CustomerName}");
        //Console.WriteLine($"{AssemblyReference.ModuleName} Received: From Total Amount: {message.TotalAmount}");
        //Console.WriteLine($"{AssemblyReference.ModuleName} Received: From Order Id: {message.OrderId}");
        //Console.WriteLine($"{AssemblyReference.ModuleName} Received: From Created At: {message.CreatedAt}");

        // Add Any Logic

        _logger.LogInformation(
            "Ending Message {@RequestName} Consumer On {@CurrentDateTime} on {Module}",
            typeof(OrderCreatedEvent).Name, DateTime.UtcNow, AssemblyReference.ModuleName);
        return Task.CompletedTask;
    }
}


6. Add Modules Extension Methods

    public static IServiceCollection AddCustomerModule(this IServiceCollection services, List<Assembly> assemblies)
    {
        assemblies.Add(AssemblyReference.Assembly);
        return services;
    }

7. In Web Api

  • Program.cs

var assemblies = new List<Assembly> { typeof(Program).Assembly };

// Add Modules Services
builder.Services.AddCartModule(assemblies);
builder.Services.AddCustomerModule(assemblies);
builder.Services.AddOrderModule(assemblies);
builder.Services.AddPaymentModule(assemblies);


// Add Messaging Service (sync in-memory bus)
//builder.Services.AddInMemoryMessaging(assemblies.ToArray());


// async in-memory bus with options
services.AddAsyncInMemoryMessaging(options =>
{
    options.MaxConcurrentMessages = 10;
    options.MaxQueueSize = 500;
    options.MaxRetries = 5;
    options.RetryDelay = TimeSpan.FromSeconds(2);
}, assemblies.ToArray());

// async in-memory bus without options
//services.AddAsyncInMemoryMessaging(assemblies: assemblies.ToArray());


.
.
.

app.MapPost("/order", async (IOrderService service, OrderRequest request) =>
{
    var result = await service.CreateOrder(request.CustomerName, request.TotalAmount);
    return Results.Ok(result);
});

app.Run();



public record OrderRequest(string CustomerName, decimal TotalAmount);

8. Download

You Can Download Project Source Code GitHub Page.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

If you encounter any issues or have questions, please file an issue on the GitHub repository.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.3 198 5/18/2025
1.0.2 187 5/17/2025
1.0.1 278 5/16/2025
1.0.0 264 5/16/2025