SmartTender.MessageBroker.AspNetCore 1.0.2

Suggested Alternatives

SmartTender.MessageBroker.AspNetCore 1.0.20

Additional Details

Can not support different R/W connections

There is a newer version of this package available.
See the version list below for details.
dotnet add package SmartTender.MessageBroker.AspNetCore --version 1.0.2                
NuGet\Install-Package SmartTender.MessageBroker.AspNetCore -Version 1.0.2                
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="SmartTender.MessageBroker.AspNetCore" Version="1.0.2" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add SmartTender.MessageBroker.AspNetCore --version 1.0.2                
#r "nuget: SmartTender.MessageBroker.AspNetCore, 1.0.2"                
#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.
// Install SmartTender.MessageBroker.AspNetCore as a Cake Addin
#addin nuget:?package=SmartTender.MessageBroker.AspNetCore&version=1.0.2

// Install SmartTender.MessageBroker.AspNetCore as a Cake Tool
#tool nuget:?package=SmartTender.MessageBroker.AspNetCore&version=1.0.2                

SmartMessageBroker NuGet Package

Overview

This NuGet package provides services for working with RabbitMQ message broker within the internal affairs of Smarttender. It offers functionality for message publishing and consuming, allowing efficient communication between different parts of your system via RabbitMQ queues.

Installation

To use this package, you can install it via NuGet Package Manager or directly add it to your project's dependencies in the .csproj file.

dotnet add package Smarttender.MessageBroker

Usage

Dependency Injection method

public static class SmartMessageBrokerServicesDi
{
    // Adding required services to the service collection
    public static IServiceCollection AddSmartMessageBroker(this IServiceCollection services, string connectionString, Action<BrokerConfig> configureReceivers = null);

    // Starting consuming queues
    public static IApplicationBuilder UseSmartMessageBrokerConsumers(this IApplicationBuilder app);
}

DI Registration Examples

using SmartMessageBroker;
using Smarttender.MessageBroker.Producer.Consumers;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
builder.Services.AddSmartMessageBroker("amqps://your-rabbitmq-url",
	cfg =>
	{
		cfg.AddCommonQueueAsyncConsumer<NewTenderBidMessageConsumer, NewTenderBidMessage>();
		cfg.AddCommonQueueAsyncConsumer<FeatureUsingMessageConsumer, FeatureUsingMessage>();
	});
var app = builder.Build();

// Configure the HTTP request pipeline.

app.UseHttpsRedirection();
app.UseSmartMessageBrokerConsumers();

app.MapControllers();

app.Run();

Replace "amqps://your-rabbitmq-url" with your actual RabbitMQ connection string.

Publisher

Service that provides you ability to send message to particular queue

public interface IMessagePublisher
{
    void Publish<T>(T message, Queue queue)
        where T: BasicMessage;
}

Publisher usage

using Microsoft.AspNetCore.Mvc;
using Smarttender.MessageBroker.Abstracts;
using Smarttender.MessageBroker.Models;


[ApiController]
[Route("api/[controller]")]
public class MessageController : ControllerBase
{
	private readonly IMessagePublisher _messagePublisher;

	public MessageController(IMessagePublisher messagePublisher)
	{
		_messagePublisher = messagePublisher ?? throw new ArgumentNullException(nameof(messagePublisher));
	}
	[HttpPost("string")]
	public IActionResult ProduceStringData()
	{
		try
		{
			var fakeMessage = new StringDataMessage
			{
				Data = Faker.Name.FullName(),
				Edrpou = Faker.RandomNumber.Next(10000000, 99999999).ToString(),
				UserLogin = Faker.Internet.UserName(),
				Segment = Faker.Lorem.GetFirstWord(),
				FeatureRole = Faker.Lorem.GetFirstWord(),
				Datestamp = DateTime.Now,
				Tags = new string[] { Faker.Lorem.GetFirstWord(), Faker.Lorem.GetFirstWord() }
			};

			// Here you can send the mock message using your IMessagePublisher implementation
			_messagePublisher.Publish(fakeMessage, Queue.Common);

			Console.WriteLine($"Produced mock message: {fakeMessage.Data}");
			return Ok();
		}
		catch (Exception ex)
		{
			Console.WriteLine($"Error producing mock message: {ex.Message}");
			return StatusCode(500, "An error occurred while producing the mock message.");
		}
	}
	[HttpPost]
	public IActionResult Produce()
	{
		try
		{
			var fakeMessage = new FeatureUsingMessage
			{
				FeatureName = Faker.Name.FullName(),
				Edrpou = Faker.RandomNumber.Next(10000000, 99999999).ToString(),
				UserLogin = Faker.Internet.UserName(),
				Segment = Faker.Lorem.GetFirstWord(),
				FeatureRole = Faker.Lorem.GetFirstWord(),
				Datestamp = DateTime.Now,
				Tags = new string[] { Faker.Lorem.GetFirstWord(), Faker.Lorem.GetFirstWord() }
			};

			// Here you can send the mock message using your IMessagePublisher implementation
			_messagePublisher.Publish(fakeMessage, Queue.Common);

			Console.WriteLine($"Produced mock message: {fakeMessage.FeatureName}");
			return Ok();
		}
		catch (Exception ex)
		{
			Console.WriteLine($"Error producing mock message: {ex.Message}");
			return StatusCode(500, "An error occurred while producing the mock message.");
		}
	}
}

Consumer

Class that implements basic sync/async consumers:

	public abstract class BasicAsyncConsumer<T> : IAsyncMessageConsumer<T>
		where T : BasicMessage
	{
		protected JsonSerializerOptions SerializerOptions { get; set; } = JsonOptions.JsonSerializerOptions<T>();
		public virtual string Filter => typeof(T).Name;
		public virtual int Ttl => 1 * 24 * 60 * 60 * 1000;
		public abstract Task<MessageDeliveryStatus> OnMessage(T message);
	}

or

	public abstract class BasicConsumer<T> : IMessageConsumer<T>
		where T : BasicMessage
	{
		protected JsonSerializerOptions SerializerOptions { get; set; } = JsonOptions.JsonSerializerOptions<T>();
		public virtual string Filter => typeof(T).Name;
		public virtual int Ttl => 1 * 24 * 60 * 60 * 1000;
		public abstract MessageDeliveryStatus OnMessage(T message);
	}

and registered in DI like in "DI Registration Examples" blok shown is represents a consumer responsible for processing messages of type <T> synchronously/asynchronously. When a message of this type is received from the RabbitMQ queue, the OnMessage method is invoked.

the message delivery acknowledgment is decided by result of OnMessagge method, that returns MessageDeliveryStatus

	public enum MessageDeliveryStatus
	{
		Acknowledged = 0,
		NotAcknowledged = 1,
	}

If OnMessagge returns MessageDeliveryStatus.Acknowledged that means message will be considered as delivered successfuly otherwise if MessageDeliveryStatus.NotAcknowledged being returned, that means message is not accepted by consumer end requeued again

Consumer example

	public class FeatureUsingMessageConsumer : BasicAsyncConsumer<FeatureUsingMessage>
	{
		public override Task<MessageDeliveryStatus> OnMessage(FeatureUsingMessage message)
		{
			// Implement the logic to process the received message
			Console.WriteLine($"Received FeatureUsingMessage: {message.FeatureName}");
			return Task.FromResult(MessageDeliveryStatus.Acknowledged);
		}
	}

Target frameworks

net462;
netstandard2.0;
netstandard2.1

Dependencies

  • Microsoft.AspNetCore.Http.Abstractions
  • Microsoft.Extensions.DependencyInjection.Abstractions
  • RabbitMQ.Client
  • System.Text.Json

Routing Scheme Overview

Consumer Registration

  1. Queue Declaration: For each consumer in the consumers collection, a queue is declared with a name constructed based on _queue, the executing assembly's name, and the consumer's message type.
  2. Queue Binding: The declared queue is bound to a common exchange (Exchange.Common) with a routing key constructed from the consumer's message type and _queue.
  3. Consumer Creation: An AsyncEventingBasicConsumer is created for each consumer, and its Received event is handled. When a message is received on the queue, the consumer's OnMessage method is invoked asynchronously.

Message Publication

  1. Routing Key: When publishing a message, the routing key is constructed from the message's type and the target queue (queue). This routing key is used to determine how the message should be routed within RabbitMQ.
  2. Exchange: The message is published to the common exchange (Exchange.Common). RabbitMQ uses the exchange to route messages to queues based on routing keys.
  3. Message Body: The message is serialized to JSON and converted to a byte array before being published to the exchange.

Routing Scheme Details

  • Exchange: A common exchange (Exchange.Common) is used for message routing.
  • Queues: Each consumer has its own queue declared with a name constructed based on _queue, the executing assembly's name, and the consumer's message type.
  • Routing Keys: Messages are published with routing keys constructed from the message type and the target queue. Consumers bind their queues to the exchange using routing keys based on their filter and _queue.
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.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.25 1,875 9/10/2024
1.0.24 103 9/10/2024
1.0.23 162 9/9/2024
1.0.22 95 9/9/2024
1.0.21 820 8/21/2024
1.0.20 4,615 8/21/2024
1.0.18 153 8/14/2024 1.0.18 is deprecated because it is no longer maintained and has critical bugs.
1.0.17 315 8/13/2024 1.0.17 is deprecated because it is no longer maintained and has critical bugs.
1.0.16 106 8/7/2024 1.0.16 is deprecated because it is no longer maintained and has critical bugs.
1.0.15 119 8/7/2024 1.0.15 is deprecated because it is no longer maintained and has critical bugs.
1.0.14 141 8/2/2024 1.0.14 is deprecated because it is no longer maintained and has critical bugs.
1.0.13 88 8/2/2024 1.0.13 is deprecated because it is no longer maintained and has critical bugs.
1.0.12 874 6/19/2024 1.0.12 is deprecated because it is no longer maintained and has critical bugs.
1.0.11 3,718 5/27/2024 1.0.11 is deprecated because it is no longer maintained and has critical bugs.
1.0.10 1,476 4/29/2024 1.0.10 is deprecated because it is no longer maintained and has critical bugs.
1.0.9 127 4/29/2024 1.0.9 is deprecated because it is no longer maintained and has critical bugs.
1.0.6 138 4/25/2024 1.0.6 is deprecated because it is no longer maintained and has critical bugs.
1.0.5 135 4/25/2024 1.0.5 is deprecated because it is no longer maintained and has critical bugs.
1.0.4 130 4/24/2024 1.0.4 is deprecated because it is no longer maintained and has critical bugs.
1.0.3 126 4/23/2024 1.0.3 is deprecated because it is no longer maintained and has critical bugs.
1.0.2 122 4/23/2024 1.0.2 is deprecated because it is no longer maintained and has critical bugs.