.NET Aspire
Aspire.Respire registers Respire clients from Aspire connection strings, with health checks,
OpenTelemetry, and logging. Use it in a .NET 8 or .NET 10 service that an AppHost starts with a
Redis, Valkey, or Azure Managed Redis reference. For a runnable AppHost, see the
.NET Aspire sample.
Install
dotnet add package Aspire.Respire
Register a client
Register clients on any IHostApplicationBuilder:
using Microsoft.Extensions.Hosting;
using Respire;
builder.AddRespireClient("cache");
builder.AddKeyedRespireClient("valkey");
- The default singleton exposes
IRespireClientandRespireClient. - A keyed client uses the connection name as its key: inject
[FromKeyedServices("valkey")] IRespireClient. - A second default registration or a duplicate key throws.
- The host owns and disposes the clients. They connect on the first command, not at startup.
Hosting resources
In the AppHost, use the normal Aspire hosting integrations and references:
var cache = builder.AddRedis("cache");
var valkey = builder.AddValkey("valkey");
builder.AddProject<Projects.Api>("api")
.WithReference(cache).WaitFor(cache)
.WithReference(valkey).WaitFor(valkey);
The hosting integrations (Redis, Valkey, and Azure Managed Redis) inject ConnectionStrings__cache
and ConnectionStrings__valkey, so the service needs no host, port, or password settings. Respire
reads TLS, username, password, and database from the string.
Configuration
Settings live under Aspire:Respire, with per-client overrides under
Aspire:Respire:<connectionName>. They apply in this order:
- Global integration settings.
- Named integration settings.
ConnectionStrings:<connectionName>.- The
configureSettingscallback. - Parse the resulting connection string into
RespireOptions. - Apply global
Aspire:Respire:Options, then namedAspire:Respire:<connectionName>:Options. - Run
configureOptionsonce, when the singleton is resolved.
{
"Aspire": {
"Respire": {
"Options": { "CommandTimeout": "00:00:05", "Connections": 1 },
"cache": {
"DisableTracing": false,
"Options": { "ClientName": "web", "ReconnectPolicy": { "MaxAttempts": 4 } }
}
}
}
}
Integration settings
| Setting | Default | Effect |
|---|---|---|
ConnectionString | null | Used when ConnectionStrings:<connectionName> is absent. |
DisableHealthChecks | false | Skips the health check registration. |
DisableTracing | false | Skips adding the Respire activity source. |
DisableMetrics | false | Skips adding the Respire meter. |
DisableLogging | false | Gives the client a null logger factory. |
Options section
Options binds scalar RespireOptions fields, endpoints, replica endpoints, hedged reads,
reconnect policy, client-side caching, and scalar TLS settings.
- Endpoint arrays accept strings such as
"localhost:6379"or objects such as{ "Host": "localhost", "Port": 6379 }. - A named array replaces the global one; an absent one inherits it. An empty array (
[]) clears the global endpoints, replica endpoints, or client-cache prefixes. - If you clear all primary endpoints, an options callback must supply them.
- Client-side cache key prefixes are strings.
KeyPrefixtakes a text prefix; see default key namespaces. - Time spans use the invariant .NET format. An empty string clears a nullable value:
"CommandTimeout": ""removes the command timeout. - An invalid value throws
InvalidOperationExceptionnaming the configuration path.
The builder's Settings property is a read-only snapshot; changing it does not affect the client.
Options callback
Set services, serializers, binary key prefixes, certificates, and TLS callbacks in code. The callback receives the parsed and bound options and can resolve services:
builder.AddRespireClient("cache", configureOptions: (services, options) => options with
{
ClientName = "web",
CredentialProvider = services.GetRequiredService<IRespireCredentialProvider>(),
});
A callback can supply endpoints when there is no connection string. Missing endpoints throw
InvalidOperationException: at registration without a callback, or when the client is resolved
with one (as does a null result).
Health checks, logging, and OpenTelemetry
All four are on by default. Turn one off globally, per connection, or in configureSettings:
builder.AddRespireClient("cache", settings => settings.DisableTracing = true);
Health checks
Checks are named respire_default_<connectionName> or respire_keyed_<connectionName>, with
the ready tag. A check reuses existing connections and opens none, so a client that has never
connected reports unhealthy. To be ready right after startup, send a bounded PING at startup, as
the sample does. See health checks.
Tracing and metrics
The integration adds the Respire activity source and meter to the host's OpenTelemetry
providers. Configure exporters yourself, for example
builder.Services.AddOpenTelemetry().UseOtlpExporter() for the Aspire dashboard.
To export command duration, call
RespireMetrics.Configure(new RespireMetricsOptions { Groups = RespireMetricGroups.Default | RespireMetricGroups.Command })
before you register providers or create clients. See observability.
Providers are per host, not per client: if any client enables a signal, every client's telemetry for it is observed. The flags only skip this integration's wiring; they do not suppress listeners registered elsewhere.
Logging
Clients use the host's logger factory. DisableLogging gives the client a null logger factory,
even if options supply another.
Cache companions
Install the companion package for each cache API you need:
| Package | Registration on an existing client builder |
|---|---|
Aspire.Respire.DistributedCaching | .AddDistributedCache(...) |
Aspire.Respire.HybridCaching | .AddHybridCache(configureCache, configureHybrid) |
Aspire.Respire.OutputCaching | .AddOutputCache(...) |
builder.AddRespireClientBuilder("cache")
.AddHybridCache(options => options.InstanceName = "app:cache:")
.AddOutputCache(options => options.InstanceName = "app:output:");
Use AddKeyedRespireClientBuilder for a keyed client. Companions reuse the host-owned client
and never dispose it.
- HybridCache uses the distributed cache as its L2. See Microsoft caching and output caching.
IDistributedCache,HybridCache, andIOutputCacheStorestay unkeyed, even with a keyed client. Choose one backend for each. If you register several, the last one wins, with its options and client.- The base
Aspire.Respirepackage has no ASP.NET Core dependency.
Azure Managed Redis with Microsoft Entra
Add Respire.Azure and an Azure credential package. Grant the identity Redis access and use its
object ID as the Redis username:
using global::Azure.Core;
using global::Azure.Identity;
using Respire.Azure;
builder.Services.AddSingleton<TokenCredential>(new DefaultAzureCredential());
builder.AddRespireClient("cache", configureOptions: (services, options) => options with
{
CredentialProvider = new RespireAzureManagedRedisCredentialProvider(
services.GetRequiredService<TokenCredential>(),
builder.Configuration["RedisIdentityObjectId"]!),
});
The hosting reference supplies the endpoint and TLS (Aspire 13.6 emits host:10000,ssl=true,
which Respire accepts). The provider refreshes Entra credentials; you own the credential. See
Azure Managed Redis.