Skip to content

messaging publishers

Brian Greco edited this page Apr 5, 2023 · 5 revisions

IMAGE Message Publishers

Message publishers are responsible for delivering messages to consumers. There can be multiple registered publishers used to dispatch messages.


IMAGEBy default, the InProcessMessage publisher is registered and responsible for delivering messages to subscribers contained within the same process as the publisher. This publisher has been used by the messaging code examples shown thus far.


Additional message publishers can be added to dispatch messages to external subscribers using technologies such as RabbitMQ, Azure Service Bus, and/or Redis. Moving the determination of how a message is delivered from the IMessagingService implementation to publishers provides a single unified interface for sending commands and publishing domain-events to multiple destinations.

Define Message Publisher

The following message publisher will be simple. If the message being published contains an attribute named "print" containing a valid color, the contents of the message will be written to the console in that color.

Create the following message publisher within the directory: Examples.Messaging.Infa/

using System;
using System.Threading;
using System.Threading.Tasks;
using NetFusion.Common.Extensions;
using NetFusion.Messaging;
using NetFusion.Messaging.Internal;
using NetFusion.Messaging.Types.Contracts;

namespace Examples.Messaging.Infra;

public class PrintMessagePublisher : IMessagePublisher
{
    public IntegrationTypes IntegrationType => IntegrationTypes.Internal;
    
    public Task PublishMessageAsync(IMessage message, CancellationToken cancellationToken)
    {
        if (message.Attributes.TryGetValue("print", out string? color))
        {
            var printColor = Enum.TryParse(color, ignoreCase: true,
                out ConsoleColor consoleColor) ? consoleColor : ConsoleColor.Gray;

            Console.ForegroundColor = printColor;
            Console.WriteLine(message.ToIndentedJson());
        }

        return Task.CompletedTask;
    }
}

Next, add the PrintMessagePublisher to the bootstrap configuration using the MessageDispatchConfig plugin configuration as follows:

// ..

// Add Plugins to the Composite-Container:
builder.Services.CompositeContainer(builder.Configuration, new SerilogExtendedLogger())
    .AddSettings()
    .AddMessaging()
    .InitPluginConfig<MessageDispatchConfig>(c =>
    {
        c.AddPublisher<PrintMessagePublisher>();  // <-- Add this line

        c.AddEnricher<MachineNameEnricher>();
        c.AddEnricher<CorrelationEnricher>();
        c.AddEnricher<DateOccurredEnricher>();
        c.AddEnricher<HostEnricher>();
    })

    .AddPlugin<InfraPlugin>()
    .AddPlugin<AppPlugin>()
    .AddPlugin<DomainPlugin>()
    .AddPlugin<WebApiPlugin>()
    .Compose();

// ..

Define Domain Event

Add the following domain-event if not already defined to the Examples.Messaging.Domain/Events directory:

using NetFusion.Messaging.Types;

namespace Demo.Domain.Events
{
    public class NewCustomerDomainEvent : DomainEvent
    {
        public string FirstName { get; }
        public string LastName { get; }

        public NewCustomerDomainEvent(string firstName, string lastName)
        {
            FirstName = firstName;
            LastName = lastName;
        }
    }
}

Define Api Model

Define a model in the following location Examples.Messaging.WebApi/Models if not already defined:

using System.ComponentModel.DataAnnotations;

namespace Examples.Messaging.WebApi.Models;

public class CustomerRegistration
{
    [Required]
    public string FirstName { get; set; } = string.Empty;
    
    [Required]
    public string LastName { get; set; } = string.Empty;
}

Define Api Controller

Add the following method to the MessagingController class:

using Examples.Messaging.Domain.Events;
using Examples.Messaging.WebApi.Models;
using Microsoft.AspNetCore.Mvc;
using NetFusion.Messaging;

namespace Examples.Messaging.WebApi.Controllers;

[ApiController, Route("api/messaging")]
public class MessageController : ControllerBase
{
    private readonly IMessagingService _messaging;

    public MessageController(IMessagingService messaging)
    {
        _messaging = messaging;
    }

    [HttpPost("print/customer/{color}")]
    public async Task<IActionResult> PrintCustomer([FromBody]CustomerRegistration model, [FromRoute]string color)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        
        var domainEvent = new NewCustomerDomainEvent(model.FirstName, model.LastName);
        domainEvent.Attributes.Add("print", color);
        
        await _messaging.PublishAsync(domainEvent);
        return Ok();
    }
}

Execute Example

Complete the following to run the example microservice and send a HTTP Post request to the example controller:

cd ./src/Examples.Messaging.WebApi
dotnet run

Post the following requests and verity that the log message is printed by the publisher in the correct color:

http://localhost:5670/api/messaging/print/customer/Yellow

IMAGE

IMAGE

Plugin Logs

If the Bootstrap logs are expanded for the Messaging Plugin to display the MessageDispatchModule logs, a child collection lists all the configured Message Publishers:

IMAGE

Clone this wiki locally