EasyCore.RedisStreams 8.0.0

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

πŸ”΄ EasyCore.RedisStreams

EasyCore.RedisStreams is a Redis Streams infrastructure client for .NET 8. Built on StackExchange.Redis, it provides DI registration, connect, consumer-group subscribe/ack, and a unified entry format (RedisHeader / type / payload). It is not tied to IEvent / EventBus β€” use it standalone, or via the EasyCore.EventBus.RedisStreams adapter.

.NET C# Redis License Version


🌍 Language


πŸ“š Table of Contents


1. 🎯 Positioning

Scenario Fit?
Publish/subscribe on Redis stream keys βœ…
Consumer groups + acknowledge βœ…
Unified type + JSON payload + retry header βœ…
Unified IEvent + handler discovery (EDA) ❌ β†’ use EasyCore.EventBus.RedisStreams
In-process local events ❌ β†’ use EasyCore.EventBus local bus

1.1 Design Principles

Principle Meaning
Infrastructure layer EndPoints, consumer groups, and stream entry fields
Standalone No dependency on the EasyCore.EventBus core package
Clear wire format Fixed field names in RedisStreamMessageFormat
Adapter-friendly The EventBus RedisStreams adapter reuses this client

2. Relation to EventBus

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  App code (JSON payload)    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚ IRedisStreamsClient
               β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ EasyCore.RedisStreams (this)β”‚  ← infrastructure client
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚ StackExchange.Redis
               β–Ό
            Redis

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ EasyCore.EventBus.RedisStreams β”‚  ← adapter: IEvent / Handler
β”‚   └── uses this client         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Package Role
EasyCore.RedisStreams Generic Redis Streams client (this package)
EasyCore.EventBus.RedisStreams Maps EventBus IEvent onto Redis Streams

3. βš™ Requirements

Item Requirement
.NET 8.0+
Dependency StackExchange.Redis 2.8.x (brought by this package)
Redis Instance with Streams support (Redis 5.0+)

4. πŸ“₯ Installation

dotnet add package EasyCore.RedisStreams

5. ⚑ Quick Start

5️⃣.1️⃣ Register DI

using EasyCore.RedisStreams;

builder.Services.EasyCoreRedisStreams(o =>
{
    o.EndPoints = new List<string> { "localhost:6379" };
    o.User = null;           // ACL user (optional)
    o.Password = null;       // password (optional)
    o.ConnectTimeout = 10;   // seconds
    o.SyncTimeout = 10;      // seconds
    o.DefaultDatabase = 0;
    o.ConsumerGroup = "RedisGroup";
    o.AppName = "MyApp";
});

5️⃣.2️⃣ Publish

public sealed class NotifyPublisher
{
    private readonly IRedisStreamsClient _client;

    public NotifyPublisher(IRedisStreamsClient client) => _client = client;

    public async Task PublishAsync(string userId, CancellationToken ct = default)
    {
        await _client.ConnectAsync(ct);

        var payload = $$"""{"userId":"{{userId}}","channel":"sms"}""";
        var header = new RedisStreamHeader
        {
            RetryCount = 0,
            RetryInterval = 5
        };

        await _client.PublishAsync(
            streamKey: "notify:sms",
            typeName: "SmsNotify",
            payloadJson: payload,
            header: header,
            cancellationToken: ct);
    }
}

5️⃣.3️⃣ Subscribe and Acknowledge

public sealed class NotifyConsumer : BackgroundService
{
    private readonly IRedisStreamsClient _client;

    public NotifyConsumer(IRedisStreamsClient client) => _client = client;

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        await _client.ConnectAsync(stoppingToken);

        await _client.SubscribeAsync(
            streamKeys: new[] { "notify:sms" },
            handler: async (msg, ct) =>
            {
                // msg.TypeName / msg.PayloadJson / msg.Header
                // handle business…

                await _client.AcknowledgeAsync(msg.StreamKey, msg.MessageId, ct);
            },
            cancellationToken: stoppingToken);
    }
}

RedisStreamsDeliveredMessage fields: StreamKey, MessageId, TypeName, PayloadJson, Header.


6. Message Format (RedisStreamMessageFormat)

Each stream entry uses fixed field names:

Constant Redis field Content
HeaderField RedisHeader JSON of RedisStreamHeader
TypeField type Logical message type name
PayloadField payload Business JSON payload

RedisStreamHeader:

Property Description
RetryCount Times processing has been retried
RetryInterval Retry interval (unit agreed by the EventBus integration layer)

When header is null, publish writes a default header.


7. 🧩 API Overview

Member Description
EasyCoreRedisStreams(Action<RedisStreamsOptions>) DI: Options and IRedisStreamsClient
ConnectAsync Connect to Redis and prepare the consumer group name
PublishAsync(streamKey, typeName, payloadJson, header?) XADD with unified fields
SubscribeAsync(streamKeys, handler) Consumer-group consume loop
AcknowledgeAsync(streamKey, messageId) XACK the entry

IRedisStreamsClient implements IAsyncDisposable β€” dispose on shutdown.


8. Options (RedisStreamsOptions)

Property Type Default Description
EndPoints List<string> empty Redis endpoints, e.g. localhost:6379
User string? null ACL username
Password string? null Password
ConnectTimeout int 10 Connect timeout (seconds, Γ—1000 internally)
SyncTimeout int 10 Sync timeout (seconds, Γ—1000 internally)
AbortOnConnectFail bool false Abort when initial connect fails
DefaultDatabase int 0 Default DB index
ConsumerGroup string RedisGroup Group name suffix (combined with AppName)
AppName string? null Group name prefix; entry assembly when null

ToConfigurationOptions() converts these settings to StackExchange.Redis.ConfigurationOptions.


9. ❓ FAQ

Q: This package vs EasyCore.EventBus.RedisStreams?
A: Use the EventBus adapter for IEvent, handlers, and retries. Use this package for stream-key + JSON I/O.

Q: Why fixed RedisHeader / type / payload?
A: So multiple services (and the EventBus adapter) can share the same stream layout.

Q: Is ConnectTimeout in milliseconds?
A: No β€” Options use seconds; values are multiplied by 1000 for StackExchange.Redis.

Q: Do I need to create the consumer group myself?
A: The client prepares the group during subscribe. Ensure Redis supports Streams and the key is consumable.

Q: Cluster / sentinel?
A: Put endpoints in EndPoints with credentials as needed; advanced topologies follow StackExchange.Redis docs.


10. πŸ“„ License

MIT OR Apache-2.0 β€” see the repository LICENSE if present, or the NuGet package metadata.


🀝 Contributing

Issues and PRs are welcome. After changing this package, verify EasyCore.EventBus.RedisStreams and related demos.

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.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on EasyCore.RedisStreams:

Package Downloads
EasyCore.EventBus.RedisStreams

.NET Core EventBus distributed transport based on Redis Streams.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
8.0.0 34 7/18/2026