Zongsoft.Externals.Redis
7.14.0
dotnet add package Zongsoft.Externals.Redis --version 7.14.0
NuGet\Install-Package Zongsoft.Externals.Redis -Version 7.14.0
<PackageReference Include="Zongsoft.Externals.Redis" Version="7.14.0" />
<PackageVersion Include="Zongsoft.Externals.Redis" Version="7.14.0" />
<PackageReference Include="Zongsoft.Externals.Redis" />
paket add Zongsoft.Externals.Redis --version 7.14.0
#r "nuget: Zongsoft.Externals.Redis, 7.14.0"
#:package Zongsoft.Externals.Redis@7.14.0
#addin nuget:?package=Zongsoft.Externals.Redis&version=7.14.0
#tool nuget:?package=Zongsoft.Externals.Redis&version=7.14.0
Zongsoft.Externals.Redis Extension Plugin Library
Overview
Zongsoft.Externals.Redis integrates Redis with the infrastructure abstractions of the Zongsoft framework. It is built on StackExchange.Redis and can be used as a plugin or referenced directly by an application.
Features
- Registers named Redis services from
Redisconnection settings. - Provides key/value, dictionary, hash-set, sequence, and distributed-lock operations.
- Implements the framework's message queue and subscription abstractions with Redis.
- Provides a reliable-message storage factory at
/Workspace/Messaging/Storages/Redis. - Supplies a Microsoft configuration provider and distributed-cache integration.
- Adds Redis inspection, mutation, counter, search, and lock commands to the Zongsoft command tree.
Load Zongsoft.Externals.Redis.plugin and configure /Externals/Redis/ConnectionSettings. Messaging connections can be configured separately under /Messaging/ConnectionSettings; both use the Redis driver. See the distributed-lock sample, the distributed-cache sample, the messaging sample, and the tests for working examples.
For reliable Broker storage, name the Redis connection exactly after the Broker and inject the factory path. The daemon-created ZeroMQ Broker is named QueueServer:
Set a stable storage identifier before the process starts:
$env:ZONGSOFT_MESSAGING_STORAGE_IDENTIFIER = "broker-storage-01"
<option path="/Externals/Redis">
<connectionSettings>
<connectionSetting connectionSetting.name="QueueServer" driver="Redis"
value="server=127.0.0.1:6379;password=;" />
</connectionSettings>
</option>
<extension path="/Workbench/Messaging/Zero">
<QueueServer.Storages>{path:/Workspace/Messaging/Storages/Redis}</QueueServer.Storages>
</extension>
The factory never falls back to a default connection. It freezes ZONGSOFT_MESSAGING_STORAGE_IDENTIFIER on first use and falls back to Environment.MachineName when the variable is empty. Storage keys use Zongsoft.Messaging.Storage:{ConnectionSettings.Name}:{StorageIdentifier} as their prefix; overlong partitions use a stable SHA-256 form.
When upgrading from the former nodeId option, set ZONGSOFT_MESSAGING_STORAGE_IDENTIFIER to the same value before starting the Broker. The partition text remains compatible when the value is unchanged; omitting it may select the machine-name partition and leave previous reliable messages under the old prefix.
Redis streams retain up to 100000 messages by default and use approximate trimming. Configure MaximumLength and UseApproximateMaximumLength in the messaging connection settings to change this behavior; use a negative MaximumLength to disable trimming. Dead-letter transfer atomically appends and acknowledges through a same-slot Lua script.
Cache notification subscriptions require Redis keyspace notifications (recommended setting: notify-keyspace-events KA). Notifications have Redis Pub/Sub at-most-once semantics and are not replayed after a disconnection.
Caches, queues, configuration providers, and the Microsoft distributed cache share one ConnectionMultiplexer when their connection options are equivalent; independent leases control ownership. Use RedisService.WithDatabase() and WithNamespace() for immutable scopes. The legacy Use() and Namespace members may only change a service before its first operation.
Notifications use one Redis subscription per scope and one bounded local queue per consumer. The default capacity is 1024, with drop-oldest overflow behavior. The configuration provider keeps a detached local snapshot and reloads it after matching key notifications.
Redis locks expose monotonically increasing fencing tokens and explicit renewal. Automatic renewal is disabled by default and is enabled only through DistributedLockOptions.RenewalInterval; an uncertain connection or failed renewal is treated as loss of ownership, so protected writes should validate fencing tokens.
RedisServiceInfo.Capabilities and RedisQueue.Capabilities expose the conservative intersection across primary nodes: XAUTOCLAIM at Redis 6.2, XACKDEL/group-aware trimming at 8.2, and Stream IDMP at 8.6. Older servers retain the existing fallback behavior. The Zongsoft.Externals.Redis diagnostics source provides both ActivitySource and Meter without requiring an additional telemetry package.
Getting Started through the Cache Contract
Business modules only reference Core's IDistributedCache; the deployment composition selects the Redis plugin. RedisService construction is not the default business entry point.
This host-option adaptation uses the Redis connection name from the actual distributed-cache sample. Supply your isolated test endpoint and credentials through environment-specific configuration. It does not add an Orders business module or a custom cache-selection key:
<options>
<option path="/Externals/Redis">
<connectionSettings>
<connectionSetting connectionSetting.name="Redis" driver="Redis"
value="server=REPLACE_WITH_HOST:REPLACE_WITH_PORT;password=REPLACE_WITH_PASSWORD;database=15" />
</connectionSettings>
</option>
</options>
This is a host-based adaptation of the sample’s cache read/write operations, using only the shared contract. The sample itself is a standalone process that owns its RedisService. After host initialization, run the fragment in a service/command:
using Zongsoft.Caching;
using Zongsoft.Services;
var application = ApplicationContext.Current;
var qualifiedName = "Redis@Redis";
var cache = application.Services.Locate<IDistributedCache>(qualifiedName)
?? throw new InvalidOperationException("The configured cache is unavailable.");
var key = "Zongsoft.Externals.Redis.Samples:" + Guid.NewGuid().ToString("N");
try
{
await cache.SetValueAsync(key, "hello", TimeSpan.FromMinutes(1));
Console.WriteLine(await cache.GetValueAsync<string>(key));
}
finally
{
await cache.RemoveAsync(key);
}
The expected output is hello. Only this call's generated key is removed; the example does not clear the database. Module code can use its own Module.Current.Services. Do not dispose the shared cache per operation.
Provider Name versus Connection Name
In Redis@Redis, Redis is the registered provider alias and Redis is the connection name passed to its GetService(name); Redis is not a module container here. You can also resolve Zongsoft.Services.IServiceProvider<IDistributedCache> and call GetService("Redis"), but explicitly select the provider when several coexist instead of relying on registration order.
RedisServiceProvider reuses services by name. Ordinary cache/sequence/lock lookup tries the default connection when a named connection is missing. Reliable message storage factories instead require an exact name. A misspelled connection can therefore fall back unexpectedly. Check selected settings during startup without printing complete connection strings.
Deployment Versions and First-Connection Troubleshooting
🚨 The current deployment manifest deploys StackExchange.Redis before the Microsoft cache adapter. The latter's transitive dependency can overwrite the DLL with an older version. In local .NET 10 verification, 2.7.27 overwrote 3.1.31 and first use failed with a missing ConfigurationOptions.get_SentinelUser method. Appearing in plugin.list does not prove that the first connection will succeed.
For the current source version, after plugin deployment and with the host stopped, use a separate supplemental manifest to deploy the required version into the same plugin directory:
[plugins zongsoft externals redis]
nuget:StackExchange.Redis@3.1.31
dotnet deploy redis-runtime.deploy --destination:./out --framework:net10.0 --overwrite:alway
Save the INI above as redis-runtime.deploy. This command overwrites files, so target a verified test deployment. The project file owns the required version; do not perpetually reuse an old workaround. Check the final DLL version, restart, and verify contract-level reads and writes.
For connection failures, check plugin dependency versions, named settings and driver, Windows/container addressing, port and credentials, then database permissions. A Windows host uses 127.0.0.1 with the published port; localhost inside a container refers to that container, not Windows.
Plugin-Based Integration
Compose this feature through the host; a package reference supplies compile-time APIs, while plugin loading also requires deployed manifests and runtime assets. See the complete plugin workflow.
The manifest registers the Redis service provider, settings driver, commands and message-storage factory. Configure named connections and resolve cache/sequence/lock contracts through the provider; applications should not recreate the shared connection per operation.
| Runtime artifact | Source of truth |
|---|---|
Zongsoft.Externals.Redis |
Zongsoft.Externals.Redis.plugin |
| File copying and dependencies | Zongsoft.Externals.Redis.deploy |
Add this fragment to an existing host .deploy (retain Main and the host’s other base manifests; do not replace the whole file):
[plugins zongsoft externals redis]
nuget:Zongsoft.Externals.Redis
Run dotnet deploy against a test deployment as explained in the workflow, with the host's framework, platform, architecture and, where needed, site. Pin compatible versions in real deployments; application dependencies such as databases, caches or commercial runtimes are still separate prerequisites.
Additional artifacts listed by the deployment manifest include Zongsoft.Externals.Redis.plugin, Zongsoft.Externals.Redis.option. Retain assemblies, dependencies and satellite resource directories as well. Restart the host after deployment, check plugin loading and service/driver registration, then verify the workflow above; copied files alone do not prove that the feature is active.
| 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 is compatible. 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 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. |
-
net10.0
- Microsoft.Extensions.Caching.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Caching.StackExchangeRedis (>= 10.0.0)
- Microsoft.Extensions.Configuration (>= 10.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.0)
- StackExchange.Redis (>= 3.1.31)
- Zongsoft.Core (>= 7.59.0)
-
net8.0
- Microsoft.Extensions.Caching.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Caching.StackExchangeRedis (>= 8.0.1)
- Microsoft.Extensions.Configuration (>= 8.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- StackExchange.Redis (>= 3.1.31)
- Zongsoft.Core (>= 7.59.0)
-
net9.0
- Microsoft.Extensions.Caching.Abstractions (>= 9.0.2)
- Microsoft.Extensions.Caching.StackExchangeRedis (>= 9.0.2)
- Microsoft.Extensions.Configuration (>= 9.0.2)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.2)
- StackExchange.Redis (>= 3.1.31)
- Zongsoft.Core (>= 7.59.0)
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 |
|---|---|---|
| 7.14.0 | 98 | 9/18/2026 |
| 7.13.0 | 121 | 8/20/2026 |
| 7.11.0 | 123 | 8/15/2026 |
| 7.10.0 | 216 | 12/31/2025 |
| 7.9.1 | 269 | 11/26/2025 |
| 7.9.0 | 279 | 10/17/2025 |
| 7.7.0 | 244 | 10/10/2025 |
| 7.6.0 | 273 | 9/25/2025 |
| 7.5.0 | 456 | 7/21/2025 |
| 7.4.0 | 288 | 6/27/2025 |
| 7.3.0 | 267 | 5/30/2025 |
| 7.2.0 | 379 | 5/16/2025 |
| 7.1.0 | 299 | 5/6/2025 |
| 7.0.0 | 284 | 2/24/2025 |