FoundationKit.Events
0.0.1
See the version list below for details.
dotnet add package FoundationKit.Events --version 0.0.1
NuGet\Install-Package FoundationKit.Events -Version 0.0.1
<PackageReference Include="FoundationKit.Events" Version="0.0.1" />
<PackageVersion Include="FoundationKit.Events" Version="0.0.1" />
<PackageReference Include="FoundationKit.Events" />
paket add FoundationKit.Events --version 0.0.1
#r "nuget: FoundationKit.Events, 0.0.1"
#:package FoundationKit.Events@0.0.1
#addin nuget:?package=FoundationKit.Events&version=0.0.1
#tool nuget:?package=FoundationKit.Events&version=0.0.1
FoundationKit.Events
⚠️ Important Note: This is beta version 0.0.1 and is not production tested. Use with caution.
FoundationKit.Events is a library designed to simplify the implementation of messaging patterns and distributed events using RabbitMQ in .NET applications. This library abstracts the complexity of configuring connections, channels, and consumers, allowing developers to focus on business logic.
🚀 Key Features
- Simplified Configuration: Quick connection to RabbitMQ via fluent configuration.
- Message Publishing: Simple abstraction for sending events.
- Event Handling (Consumers): Automatic discovery and execution system for handlers to process messages.
- Resilience: Automatic handling of retries and acknowledgments (ACK/NACK).
⚙️ Configuration
To get started, you need to configure the services in your dependency injection (DI) container.
1. Define Configuration (RabbitConfig)
The RabbitConfig class controls how the library connects to RabbitMQ and how exchanges behave.
| Property | Description | Default Value |
|---|---|---|
Host |
RabbitMQ server address. | localhost |
Port |
Connection port. | 5672 (or AMQP default) |
User |
RabbitMQ user. | guest |
Password |
User password. | guest |
Url |
Full connection string (optional). If used, overrides Host/User/Pass. | null |
DefaultExchange |
Name of the main Exchange where messages will be published. | Required |
DefaultExchangeType |
Type of Exchange (Topic, Direct, Fanout, etc.). | ExchangeType.Topic |
RedeliverUnackedMessages |
If true, failed messages (NACK) are requeued. |
true |
QueuePrefix |
Prefix for queue names (e.g., "MyApp"). | Required |
2. Register Services
Use the AddEvents extension method in your Program.cs or Startup.cs:
using FoundationKit.Events.Extensions;
using FoundationKit.Events.RabbitMQ.Config;
var rabbitConfig = new RabbitConfig
{
Host = "localhost",
User = "guest",
Password = "guest",
DefaultExchange = "my-main-exchange",
QueuePrefix = "OrderService"
};
builder.Services.AddEvents(rabbitConfig);
What does AddEvents do internally?
- Establishes the connection with RabbitMQ.
- Creates a communication channel.
- Declares the default Exchange if it doesn't exist.
- Registers the
IRabbitMessageBrokerpublishing service. - Automatically scans all assemblies for classes implementing
IMessageHandler<T>. - Starts the
RabbitMqConsumerServicein the background to listen for messages.
📨 Usage
1. Define a Message
A message is simply a class (POCO) that implements the marker interface IMessage.
using FoundationKit.Events.RabbitMQ.Messages;
public class UserCreatedEvent : IMessage
{
public Guid UserId { get; set; }
public string Email { get; set; }
}
2. Publish a Message
Inject IRabbitMessageBroker and use the PublishAsync method.
public class UserService
{
private readonly IRabbitMessageBroker _broker;
public UserService(IRabbitMessageBroker broker)
{
_broker = broker;
}
public async Task CreateUser(User user)
{
// ... creation logic ...
var eventMessage = new UserCreatedEvent { UserId = user.Id, Email = user.Email };
// Publishes the message to the default exchange
await _broker.PublishAsync(eventMessage);
}
}
Details of PublishAsync:
- Wraps your message in an
EventMessage<T>envelope that includes metadata (Message ID, date, CorrelationId). - Serializes the message to JSON.
- Sends it to RabbitMQ using the Routing Key (by default, the event name, e.g., "UserCreatedEvent").
3. Consume (Handle) a Message
To react to an event, create a class that implements IMessageHandler<T>.
using FoundationKit.Events.RabbitMQ.Handlers;
public class SendWelcomeEmailHandler : IMessageHandler<UserCreatedEvent>
{
public async Task HandleAsync(UserCreatedEvent message, CancellationToken cancellationToken)
{
Console.WriteLine($"Sending email to: {message.Email}");
// Logic to send email...
}
}
4. Register the Subscriber (Queue)
For your application to actually listen for messages of that type, you must explicitly declare that you want to subscribe. This creates the queue in RabbitMQ and binds it to the Exchange.
// In Program.cs, after AddEvents
builder.Services.AddSubscriber<UserCreatedEvent>();
What does AddSubscriber<T> do?
- Declares a queue with the format
{QueuePrefix}:{MessageName}(e.g.,OrderService:UserCreatedEvent). - Binds that queue to the configured Exchange using the message name as the Routing Key.
- From this moment on, RabbitMQ will route
UserCreatedEventmessages to this queue.
🧠 Internal Functionality
RabbitMqConsumerService
It is a BackgroundService that runs while your application is alive.
- Listening: Maintains an active consumer connected to the declared queues.
- Deserialization: When a message arrives, it reads the message type from RabbitMQ's BasicProperties and deserializes the JSON.
- Invocation: Creates a dependency injection Scope, looks for the corresponding
IMessageHandler<T>registered in the container, and executes theHandleAsyncmethod. - Ack/Nack:
- If everything goes well, it sends an ACK (acknowledgment) to RabbitMQ to remove the message from the queue.
- If an exception occurs, it sends a NACK. If
RedeliverUnackedMessagesis true, the message returns to the queue to be retried.
Message Structure in RabbitMQ
The library does not send your "raw" JSON object. It wraps it in a standard structure to maintain traceability:
{
"Data": { ... your message object ... },
"Id": "message-guid",
"CreationDate": "2023-10-27T10:00:00Z",
"Metadata": {
"CorrelationId": "...",
...
}
}
This allows the system to handle additional metadata without cluttering your domain classes.
| Product | Versions 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. net9.0 was computed. 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. |
-
net8.0
- Foundationkit.Extensions (>= 4.0.5)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- RabbitMQ.Client (>= 7.2.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.