Teamforapps.Messaging.Kafka 1.0.10

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

Teamforapps.Messaging.Kafka

Kafka producer/consumer library for Teamforapps microservices. Wraps Confluent.Kafka with idempotent publishing, Polly retry, and an optional EF Core transactional outbox — wired up through a single AddKafkaMsgService(...) call.

NuGet package ID: Teamforapps.Messaging.Kafka | Target framework: .NET 10

Features

  • IIntegrationEventPublisher — produce events with an idempotent singleton Confluent.Kafka producer
  • IIntegrationEventHandler<T> — type-safe consumer handlers with per-message DI scope and Polly retry
  • [Topic("name")] attribute — explicit topic mapping; fallback is lowercased class name with "Event" suffix stripped
  • EF Core transactional outbox — write event and business data in the same DB transaction; background service drains to Kafka
  • Single fluent DI registration: AddKafkaMsgService(...)

Quick start

1. Install

dotnet add package Teamforapps.Messaging.Kafka

2. Define an integration event

using Teamforapps.Messaging.Kafka.Abstractions;
using Teamforapps.Messaging.Kafka.Topics;

[Topic("profile.created")]
public sealed record ProfileCreated(Guid EventId, DateTime OccurredAt, Guid ProfileId, string UserId)
    : IIntegrationEvent;

IIntegrationEvent requires EventId: Guid and OccurredAt: DateTime.

3. Configure appsettings.json

"Kafka": {
  "BootstrapServers": "localhost:29092",
  "ClientId": "profile-api",
  "ConsumerGroup": "profile-api"
}

All values can also be set via environment variables (e.g. Kafka__BootstrapServers).

4. Register in Program.cs

Producer only:

builder.Services.AddKafkaMsgService(builder.Configuration);

Consumer:

builder.Services.AddKafkaMsgService(builder.Configuration, b => b
    .Subscribe<ProfileCreated, IndexProfileOnCreated>()
    .Subscribe<ProfileDeleted, RemoveProfileFromIndex>());

Producer + outbox:

builder.Services.AddKafkaMsgService(builder.Configuration, b =>
    b.AddOutbox<ApplicationDbContext>());

Inline options (no config file):

builder.Services.AddKafkaMsgService(o =>
{
    o.BootstrapServers = "localhost:29092";
    o.ClientId = "profile-api";
    o.ConsumerGroup = "profile-api";
});

5. Publish an event

public class CreateProfileHandler(IIntegrationEventPublisher publisher)
{
    public async Task HandleAsync(CreateProfileCommand cmd, CancellationToken ct)
    {
        // ... business logic ...
        await publisher.PublishAsync(new ProfileCreated(Guid.NewGuid(), DateTime.UtcNow, profile.Id, cmd.UserId), ct);
    }
}

To publish to a specific partition, pass an explicit key:

await publisher.PublishAsync(evt, partitionKey: profile.Id.ToString(), ct);

6. Handle an event

public sealed class IndexProfileOnCreated : IIntegrationEventHandler<ProfileCreated>
{
    public async Task HandleAsync(ProfileCreated e, CancellationToken ct)
    {
        // index the profile in search
    }
}

Handlers are registered as scoped services, so they can depend on DbContext, unit-of-work, or any other scoped dependency.

Outbox pattern

When AddOutbox<TContext>() is called, IIntegrationEventPublisher is replaced with a version that writes an outbox_messages row inside the current EF transaction. A background service (OutboxPublisherHostedService) polls the table and produces to Kafka.

Add to OnModelCreating:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.ConfigureOutbox();
}

Generate the migration:

dotnet ef migrations add AddOutbox -p src/YourService.Infrastructure -s src/YourService.API

Configuration reference

All sections are optional — defaults are shown.

Kafka (root)

Key Default Env var
BootstrapServers localhost:29092 Kafka__BootstrapServers
ClientId myn-service Kafka__ClientId
ConsumerGroup myn-default Kafka__ConsumerGroup

Kafka:Producer

Key Default Env var
EnableIdempotence true Kafka__Producer__EnableIdempotence
MessageTimeoutMs 30000 Kafka__Producer__MessageTimeoutMs
MessageSendMaxRetries 2147483647 Kafka__Producer__MessageSendMaxRetries

Kafka:Consumer

Key Default Env var
AutoOffsetReset earliest Kafka__Consumer__AutoOffsetReset
MaxPollIntervalMs 300000 Kafka__Consumer__MaxPollIntervalMs
RetryCount 3 Kafka__Consumer__RetryCount
RetryBaseDelay 00:00:01 Kafka__Consumer__RetryBaseDelay

Kafka:Outbox

Key Default Env var
PollInterval 00:00:01 Kafka__Outbox__PollInterval
BatchSize 50 Kafka__Outbox__BatchSize
TableName outbox_messages Kafka__Outbox__TableName

Consumer retry behaviour

Failed handlers are retried with exponential backoff (RetryCount attempts, base delay RetryBaseDelay). After all retries are exhausted the consumer stops (fail-fast). A dead-letter queue strategy is planned for v2.

Key abstractions

Interface Role
IIntegrationEvent Marker — requires EventId: Guid and OccurredAt: DateTime
IIntegrationEventPublisher Publish an event (with optional partition key)
IIntegrationEventHandler<T> Handle a consumed event
ITopicResolver Map an event type to a Kafka topic name
IEventSerializer Serialize/deserialize events (default: JSON)
IOutboxStore Persist and drain outbox messages

Local development

# Start Kafka + AKHQ UI
cd deployments && docker compose up -d kafka akhq
# AKHQ UI: http://localhost:8080
# Kafka:   localhost:29092

# Run tests
dotnet test tests/Myn.Messaging.Kafka.Tests/

# Pack NuGet
dotnet pack src/Teamforapps.Messaging.Kafka -c Release -o ./nupkgs

License

MIT

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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.10 279 5/13/2026
1.0.9 110 5/10/2026
1.0.8 111 5/5/2026
1.0.7 99 5/5/2026
1.0.6 102 5/5/2026
1.0.5 102 5/3/2026
1.0.4 109 4/27/2026
1.0.3 101 4/27/2026
1.0.2 110 4/25/2026
1.0.1 109 4/25/2026
1.0.0 110 4/25/2026