DI Integration
This guide describes VibeMQ integration with Microsoft.Extensions.DependencyInjection.
Overview
VibeMQ provides packages for convenient Dependency Injection integration:
VibeMQ.Server.DependencyInjection— for serverVibeMQ.Client.DependencyInjection— for client
These packages register necessary services in the DI container and automatically manage component lifecycle.
Package Installation
dotnet add package VibeMQ.Server.DependencyInjection
dotnet add package VibeMQ.Client.DependencyInjection
Server Integration
Basic Registration
using VibeMQ.Server.DependencyInjection;
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services => {
services.AddVibeMQBroker();
})
.Build();
await host.RunAsync();
The server will start automatically when the host starts.
Registration with Configuration
using VibeMQ.Server.DependencyInjection;
using VibeMQ.Core.Enums;
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services => {
services.AddVibeMQBroker(options => {
options.Port = 8080;
options.EnableAuthentication = true;
options.AuthToken = "my-secret-token";
options.QueueDefaults.DefaultDeliveryMode = DeliveryMode.RoundRobin;
options.QueueDefaults.MaxQueueSize = 10_000;
options.QueueDefaults.EnableAutoCreate = true;
});
})
.Build();
await host.RunAsync();
Configuration from appsettings.json
appsettings.json:
{
"VibeMQ": {
"Port": 8080,
"EnableAuthentication": true,
"AuthToken": "my-secret-token",
"QueueDefaults": {
"DefaultDeliveryMode": "RoundRobin",
"MaxQueueSize": 10000,
"EnableAutoCreate": true
}
}
}
Program.cs:
using VibeMQ.Server.DependencyInjection;
var host = Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) => {
config.AddJsonFile("appsettings.json");
})
.ConfigureServices((context, services) => {
services.AddVibeMQBroker(
context.Configuration.GetSection("VibeMQ")
);
})
.Build();
await host.RunAsync();
Advanced Configuration
using VibeMQ.Server.DependencyInjection;
using VibeMQ.Core.Enums;
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services => {
services.AddVibeMQBroker(options => {
// Basic settings
options.Port = 8080;
options.MaxConnections = 5000;
options.MaxMessageSize = 2_097_152;
// Authentication
options.EnableAuthentication = true;
options.AuthToken = Environment.GetEnvironmentVariable("VIBEMQ_TOKEN");
// Queues
options.QueueDefaults.DefaultDeliveryMode = DeliveryMode.FanOutWithAck;
options.QueueDefaults.MaxQueueSize = 100_000;
options.QueueDefaults.EnableDeadLetterQueue = true;
options.QueueDefaults.MaxRetryAttempts = 5;
options.QueueDefaults.MessageTtl = TimeSpan.FromHours(24);
// Rate limiting
options.RateLimit.Enabled = true;
options.RateLimit.MaxConnectionsPerIpPerWindow = 100;
options.RateLimit.MaxMessagesPerClientPerSecond = 5000;
// TLS
options.Tls.Enabled = true;
options.Tls.CertificatePath = "/etc/ssl/vibemq.pfx";
options.Tls.CertificatePassword = Environment.GetEnvironmentVariable("CERT_PASSWORD");
});
// Health checks
services.AddHealthChecks()
.AddCheck<VibeMQHealthCheck>("vibemq");
})
.Build();
await host.RunAsync();
Client Integration
A single call to AddVibeMQClient registers:
``IVibeMQClient`` — a shared, lazily-connected client (Singleton). Inject it into any service and use
PublishAsync/SubscribeAsync; the connection is established on first use. No need to callConnectAsyncor dispose the client yourself; the host manages its lifecycle.``IVibeMQClientFactory`` — use when you need a dedicated client instance that you create and dispose yourself (e.g.
await using var client = await factory.CreateAsync()).
Basic Registration
using VibeMQ.Client;
using VibeMQ.Client.DependencyInjection;
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services => {
services.AddVibeMQClient();
})
.Build();
// Option A: inject IVibeMQClient (shared client, connects on first use)
var client = host.Services.GetRequiredService<IVibeMQClient>();
await client.PublishAsync("queue", new { Message = "Hello" });
// Option B: create a dedicated client (you dispose it)
var factory = host.Services.GetRequiredService<IVibeMQClientFactory>();
await using var dedicatedClient = await factory.CreateAsync();
await dedicatedClient.PublishAsync("queue", new { Message = "Hello" });
Registration with Configuration
using VibeMQ.Client.DependencyInjection;
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services => {
services.AddVibeMQClient(settings => {
settings.Host = "localhost";
settings.Port = 8080;
settings.ClientOptions.AuthToken = "my-secret-token";
});
})
.Build();
Configuration from appsettings.json
appsettings.json:
{
"VibeMQClient": {
"Host": "localhost",
"Port": 8080,
"ClientOptions": {
"AuthToken": "my-secret-token",
"KeepAliveInterval": "00:00:30",
"CommandTimeout": "00:00:10",
"ReconnectPolicy": {
"MaxAttempts": 10,
"InitialDelay": "00:00:01",
"MaxDelay": "00:05:00",
"UseExponentialBackoff": true
}
}
}
}
Program.cs:
using VibeMQ.Client.DependencyInjection;
var host = Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) => {
config.AddJsonFile("appsettings.json");
})
.ConfigureServices((context, services) => {
services.AddVibeMQClient(
context.Configuration.GetSection("VibeMQClient")
);
})
.Build();
Advanced Client Configuration
using VibeMQ.Client.DependencyInjection;
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services => {
services.AddVibeMQClient(settings => {
settings.Host = "vibemq.internal";
settings.Port = 8080;
settings.ClientOptions.AuthToken = Environment.GetEnvironmentVariable("VIBEMQ_TOKEN");
settings.ClientOptions.KeepAliveInterval = TimeSpan.FromSeconds(30);
settings.ClientOptions.CommandTimeout = TimeSpan.FromSeconds(10);
settings.ClientOptions.ReconnectPolicy = new ReconnectPolicy {
MaxAttempts = 10,
InitialDelay = TimeSpan.FromSeconds(1),
MaxDelay = TimeSpan.FromMinutes(5),
UseExponentialBackoff = true
};
settings.ClientOptions.UseTls = true;
settings.ClientOptions.SkipCertificateValidation = false;
});
})
.Build();
Using in Services
Publishing Messages from Service (IVibeMQClient)
The simplest approach is to inject IVibeMQClient. The client connects lazily on first use; no manual ConnectAsync or disposal in your service.
using VibeMQ.Client;
using VibeMQ.Client.DependencyInjection;
public class OrderService {
private readonly IVibeMQClient _vibeMQ;
private readonly ILogger<OrderService> _logger;
public OrderService(IVibeMQClient vibeMQ, ILogger<OrderService> logger) {
_vibeMQ = vibeMQ;
_logger = logger;
}
public async Task CreateOrderAsync(Order order) {
await _vibeMQ.PublishAsync("orders.created", new {
OrderId = order.Id,
Amount = order.Amount,
CustomerId = order.CustomerId,
CreatedAt = DateTime.UtcNow
});
_logger.LogInformation("Order {OrderId} created", order.Id);
}
}
Service registration:
services.AddScoped<OrderService>();
Publishing with IVibeMQClientFactory (dedicated client)
If you prefer a dedicated client instance per operation (you create and dispose it):
using VibeMQ.Client.DependencyInjection;
public class OrderService {
private readonly IVibeMQClientFactory _clientFactory;
private readonly ILogger<OrderService> _logger;
public OrderService(
IVibeMQClientFactory clientFactory,
ILogger<OrderService> logger) {
_clientFactory = clientFactory;
_logger = logger;
}
public async Task CreateOrderAsync(Order order) {
await using var client = await _clientFactory.CreateAsync();
await client.PublishAsync("orders.created", new {
OrderId = order.Id,
Amount = order.Amount,
CustomerId = order.CustomerId,
CreatedAt = DateTime.UtcNow
});
_logger.LogInformation("Order {OrderId} created", order.Id);
}
}
services.AddScoped<OrderService>();
Subscribing to Messages in Background Service
You can use either IVibeMQClient (shared, lazy-connected) or IVibeMQClientFactory. Example with IVibeMQClient:
using VibeMQ.Client;
using VibeMQ.Client.DependencyInjection;
public class OrderProcessor : BackgroundService {
private readonly IVibeMQClient _vibeMQ;
private readonly ILogger<OrderProcessor> _logger;
public OrderProcessor(IVibeMQClient vibeMQ, ILogger<OrderProcessor> logger) {
_vibeMQ = vibeMQ;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
await using var subscription = await _vibeMQ.SubscribeAsync<OrderCreated>(
"orders.created",
async order => {
_logger.LogInformation("Processing order {OrderId}", order.OrderId);
await ProcessOrderAsync(order, stoppingToken);
},
stoppingToken
);
_logger.LogInformation("OrderProcessor started");
try {
await Task.Delay(Timeout.Infinite, stoppingToken);
} catch (OperationCanceledException) {
_logger.LogInformation("OrderProcessor stopped");
}
}
private Task ProcessOrderAsync(OrderCreated order, CancellationToken ct) {
return Task.CompletedTask;
}
}
public class OrderCreated {
public string OrderId { get; set; }
public decimal Amount { get; set; }
public string CustomerId { get; set; }
public DateTime CreatedAt { get; set; }
}
Background service registration:
services.AddHostedService<OrderProcessor>();
Event Bus with DI
A thin event-bus wrapper around IVibeMQClient (shared client, lazy connection):
using VibeMQ.Client;
using VibeMQ.Client.DependencyInjection;
public interface IEventBus {
Task PublishAsync<T>(string eventType, T eventData, CancellationToken ct = default);
Task<IAsyncDisposable> SubscribeAsync<T>(string eventType, Func<T, Task> handler, CancellationToken ct = default);
}
public class VibeMQEventBus : IEventBus {
private readonly IVibeMQClient _client;
private readonly ILogger<VibeMQEventBus> _logger;
public VibeMQEventBus(IVibeMQClient client, ILogger<VibeMQEventBus> logger) {
_client = client;
_logger = logger;
}
public async Task PublishAsync<T>(string eventType, T eventData, CancellationToken ct = default) {
await _client.PublishAsync($"events.{eventType}", eventData, ct);
_logger.LogInformation("Event {EventType} published", eventType);
}
public async Task<IAsyncDisposable> SubscribeAsync<T>(string eventType, Func<T, Task> handler, CancellationToken ct = default) {
return await _client.SubscribeAsync<T>(
$"events.{eventType}",
async eventData => {
_logger.LogInformation("Received event {EventType}", eventType);
await handler(eventData);
},
ct
);
}
}
Registration:
services.AddSingleton<IEventBus, VibeMQEventBus>();
Usage:
public class OrderService {
private readonly IEventBus _eventBus;
public OrderService(IEventBus eventBus) {
_eventBus = eventBus;
}
public async Task CreateOrderAsync(Order order) {
await SaveOrderAsync(order);
await _eventBus.PublishAsync("order.created", new {
OrderId = order.Id,
Amount = order.Amount
});
}
}
Combined Usage
Server + Client in One Application
using VibeMQ.Server.DependencyInjection;
using VibeMQ.Client.DependencyInjection;
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services => {
// Broker server
services.AddVibeMQBroker(options => {
options.Port = 8080;
options.EnableAuthentication = true;
options.AuthToken = "my-token";
});
// Client for local publishing
services.AddVibeMQClient(settings => {
settings.Host = "localhost";
settings.Port = 8080;
settings.ClientOptions.AuthToken = "my-token";
});
})
.Build();
await host.RunAsync();
Multiple brokers
To use multiple brokers, register multiple named configurations and resolve the appropriate factory or client by name (e.g. via a custom factory or keyed services if your app supports them). By default, one AddVibeMQClient call registers a single shared IVibeMQClient and one IVibeMQClientFactory for that configuration.
Configuration via Environment Variables
For Docker and cloud deployments:
Environment variables:
# Server
VIBEMQ__PORT=8080
VIBEMQ__ENABLEAUTHENTICATION=true
VIBEMQ__AUTHTOKEN=my-secret-token
VIBEMQ__QUEUEDEFAULTS__DEFAULTDELIVERYMODE=RoundRobin
VIBEMQ__QUEUEDEFAULTS__MAXQUEUESIZE=10000
# Client
VIBEMQCLIENT__HOST=vibemq-server
VIBEMQCLIENT__PORT=8080
VIBEMQCLIENT__CLIENTOPTIONS__AUTHTOKEN=my-secret-token
Program.cs:
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) => {
services.AddVibeMQBroker(
context.Configuration.GetSection("VibeMQ")
);
services.AddVibeMQClient(
context.Configuration.GetSection("VibeMQClient")
);
})
.Build();
await host.RunAsync();
Docker Compose Example
version: '3.8'
services:
vibemq:
image: vibemq-server:latest
environment:
- VIBEMQ__PORT=8080
- VIBEMQ__ENABLEAUTHENTICATION=true
- VIBEMQ__AUTHTOKEN=${VIBEMQ_TOKEN}
ports:
- "8080:8080"
- "8081:8081"
my-app:
image: my-app:latest
environment:
- VIBEMQCLIENT__HOST=vibemq
- VIBEMQCLIENT__PORT=8080
- VIBEMQCLIENT__CLIENTOPTIONS__AUTHTOKEN=${VIBEMQ_TOKEN}
depends_on:
- vibemq
Troubleshooting
Error: “Broker already registered”
Cause: Attempting to register broker multiple times.
Solution: Make sure AddVibeMQBroker is called only once.
Error: “Unable to connect”
Cause: Server is not started yet when creating client.
Solution: When using IVibeMQClient, the client connects lazily on first use (e.g. first PublishAsync or SubscribeAsync), so ensure the broker is running by then. When using IVibeMQClientFactory, create the client after the host (and broker) have started:
await host.StartAsync(); // Server started
var factory = host.Services.GetRequiredService<IVibeMQClientFactory>();
await using var client = await factory.CreateAsync();
Auto-start Server
Server starts automatically as IHostedService. For manual control:
services.AddVibeMQBroker(options => { ... });
// Get instance
var broker = host.Services.GetRequiredService<BrokerServer>();
Next Steps
Server Setup — server setup
Client Usage — client usage
Monitoring — monitoring