/aspire-service-defaults
Create a shared ServiceDefaults project for Aspire applications. Centralizes OpenTelemetry, health checks, resilience, and service discovery configuration across all services.
$ npx -y skills add aaronontheweb/dotnet-skills --skill aspire-service-defaults --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/aspire-service-defaults
Context preview
The summary Claude sees to decide when to auto-load this skill.
Create a shared ServiceDefaults project for Aspire applications. Centralizes OpenTelemetry, health checks, resilience, and service discovery configuration across all services.
SKILL.md
aspire-service-defaults.SKILL.mdname: aspire-service-defaults
description: Create a shared ServiceDefaults project for Aspire applications. Centralizes OpenTelemetry, health checks, resilience, and service discovery configuration across all services.
invocable: false
Aspire Service Defaults
When to Use This Skill
Use this skill when:
- Building Aspire-based distributed applications
- Need consistent observability (logging, tracing, metrics) across services
- Want shared health check configuration
- Configuring HttpClient resilience and service discovery
---
What is ServiceDefaults?
ServiceDefaults is a shared project that provides common configuration for all services in an Aspire application:
- **OpenTelemetry** - Logging, tracing, and metrics
- **Health Checks** - Readiness and liveness endpoints
- **Service Discovery** - Automatic service resolution
- **HTTP Resilience** - Retry and circuit breaker policies
Every service references this project and calls `AddServiceDefaults()`.
---
Project Structure
src/
MyApp.ServiceDefaults/
Extensions.cs
MyApp.ServiceDefaults.csproj
MyApp.Api/
Program.cs # Calls AddServiceDefaults()
MyApp.Worker/
Program.cs # Calls AddServiceDefaults()
MyApp.AppHost/
Program.cs---
ServiceDefaults Project
Project File
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<IsAspireSharedProject>true</IsAspireSharedProject>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Extensions.Http.Resilience" />
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" />
</ItemGroup>
</Project>Extensions.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Logging;
using OpenTelemetry;
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;
namespace Microsoft.Extensions.Hosting;
public static class Extensions
{
private const string HealthEndpointPath = "/health";
private const string AlivenessEndpointPath = "/alive";
/// <summary>
/// Adds common Aspire services: OpenTelemetry, health checks,
/// service discovery, and HTTP resilience.
/// </summary>
public static TBuilder AddServiceDefaults<TBuilder>(this TBuilder builder)
where TBuilder : IHostApplicationBuilder
{
builder.ConfigureOpenTelemetry();
builder.AddDefaultHealthChecks();
builder.Services.AddServiceDiscovery();
builder.Services.ConfigureHttpClientDefaults(http =>
{
// Resilience: retries, circuit breaker, timeouts
http.AddStandardResilienceHandler();
// Service discovery: resolve service names to addresses
http.AddServiceDiscovery();
});
return builder;
}
public static TBuilder ConfigureOpenTelemetry<TBuilder>(this TBuilder builder)
where TBuilder : IHostApplicationBuilder
{
// Logging
builder.Logging.AddOpenTelemetry(logging =>
{
logging.IncludeFormattedMessage = true;
logging.IncludeScopes = true;
});
builder.Services.AddOpenTelemetry()
// Metrics
.WithMetrics(metrics =>
{
metrics
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddRuntimeInstrumentation();
})
// Tracing
.WithTracing(tracing =>
{
tracing
.AddSource(builder.Environment.ApplicationName)
.AddAspNetCoreInstrumentation(options =>
// Exclude health checks from traces
options.Filter = context =>
!context.Request.Path.StartsWithSegments(HealthEndpointPath) &&
!context.Request.Path.StartsWithSegments(AlivenessEndpointPath))
.AddHttpClientInstrumentation();
});
builder.AddOpenTelemetryExporters();
return builder;
}
private static TBuilder AddOpenTelemetryExporters<TBuilder>(this TBuilder builder)
where TBuilder : IHostApplicationBuilder
{
// Use OTLP exporter if endpoint is configured (Aspire Dashboard, Jaeger, etc.)
var useOtlp = !string.IsNullOrWhiteSpace(
builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);
if (useOtlp)
{
builder.Services.AddOpenTelemetry().UseOtlpExporter();
}
return builder;
}
public static TBuilder AddDefaultHealthChecks<TBuilder>(this TBuilder builder)
where TBuilder : IHostApplicationBuilder
{
builder.Services.AddHealthChecks()
.AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]);
return builder;
}
/// <summary>
/// Maps health check endpoints. Call after UseRouting().
/// </summary>
public static WebApplication MapDefaultEndpoints(this WebApplication app)
{
// Only expose in development - see security note below
if (app.Environment.IsDevelopment())
{
// Readiness: all health checks must pass
app.MapHealthChecks(HealthEndpointPath);
// Liveness: only "live" tagged checks
app.MapHealthChecks(AlivenessEndpointPath, new HealthChRead more
name: aspire-service-defaults description: Create a shared ServiceDefaults project for Aspire applications. Centralizes OpenTelemetry, health checks, resilience, and service discovery configuration across all services. invocable: false
Aspire Service Defaults
When to Use This Skill
Use this skill when:
- Building Aspire-based distributed applications
- Need consistent observability (logging, tracing, metrics) across services
- Want shared health check configuration
- Configuring HttpClient resilience and service discovery
---
What is ServiceDefaults?
ServiceDefaults is a shared project that provides common configuration for all services in an Aspire application:
- **OpenTelemetry** - Logging, tracing, and metrics
- **Health Checks** - Readiness and liveness endpoints
- **Service Discovery** - Automatic service resolution
- **HTTP Resilience** - Retry and circuit breaker policies
Every service references this project and calls `AddServiceDefaults()`.
---
Project Structure
src/
MyApp.ServiceDefaults/
Extensions.cs
MyApp.ServiceDefaults.csproj
MyApp.Api/
Program.cs # Calls AddServiceDefaults()
MyApp.Worker/
Program.cs # Calls AddServiceDefaults()
MyApp.AppHost/
Program.cs---
ServiceDefaults Project
Project File
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<IsAspireSharedProject>true</IsAspireSharedProject>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Extensions.Http.Resilience" />
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" />
</ItemGroup>
</Project>Extensions.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Logging;
using OpenTelemetry;
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;
namespace Microsoft.Extensions.Hosting;
public static class Extensions
{
private const string HealthEndpointPath = "/health";
private const string AlivenessEndpointPath = "/alive";
/// <summary>
/// Adds common Aspire services: OpenTelemetry, health checks,
/// service discovery, and HTTP resilience.
/// </summary>
public static TBuilder AddServiceDefaults<TBuilder>(this TBuilder builder)
where TBuilder : IHostApplicationBuilder
{
builder.ConfigureOpenTelemetry();
builder.AddDefaultHealthChecks();
builder.Services.AddServiceDiscovery();
builder.Services.ConfigureHttpClientDefaults(http =>
{
// Resilience: retries, circuit breaker, timeouts
http.AddStandardResilienceHandler();
// Service discovery: resolve service names to addresses
http.AddServiceDiscovery();
});
return builder;
}
public static TBuilder ConfigureOpenTelemetry<TBuilder>(this TBuilder builder)
where TBuilder : IHostApplicationBuilder
{
// Logging
builder.Logging.AddOpenTelemetry(logging =>
{
logging.IncludeFormattedMessage = true;
logging.IncludeScopes = true;
});
builder.Services.AddOpenTelemetry()
// Metrics
.WithMetrics(metrics =>
{
metrics
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddRuntimeInstrumentation();
})
// Tracing
.WithTracing(tracing =>
{
tracing
.AddSource(builder.Environment.ApplicationName)
.AddAspNetCoreInstrumentation(options =>
// Exclude health checks from traces
options.Filter = context =>
!context.Request.Path.StartsWithSegments(HealthEndpointPath) &&
!context.Request.Path.StartsWithSegments(AlivenessEndpointPath))
.AddHttpClientInstrumentation();
});
builder.AddOpenTelemetryExporters();
return builder;
}
private static TBuilder AddOpenTelemetryExporters<TBuilder>(this TBuilder builder)
where TBuilder : IHostApplicationBuilder
{
// Use OTLP exporter if endpoint is configured (Aspire Dashboard, Jaeger, etc.)
var useOtlp = !string.IsNullOrWhiteSpace(
builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);
if (useOtlp)
{
builder.Services.AddOpenTelemetry().UseOtlpExporter();
}
return builder;
}
public static TBuilder AddDefaultHealthChecks<TBuilder>(this TBuilder builder)
where TBuilder : IHostApplicationBuilder
{
builder.Services.AddHealthChecks()
.AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]);
return builder;
}
/// <summary>
/// Maps health check endpoints. Call after UseRouting().
/// </summary>
public static WebApplication MapDefaultEndpoints(this WebApplication app)
{
// Only expose in development - see security note below
if (app.Environment.IsDevelopment())
{
// Readiness: all health checks must pass
app.MapHealthChecks(HealthEndpointPath);
// Liveness: only "live" tagged checks
app.MapHealthChecks(AlivenessEndpointPath, new HealthChA comprehensive AI coding plugin with 30 skills and 5 specialized agents for professional .NET development. Battle-tested patterns from production systems covering C#, Akka.NET, Aspire, EF Core, testing, and performance optimization.
Other skills on dotnet-skills.
- /akka-aspire-configuration
Configure Akka.NET with .NET Aspire for local development and production deployments. Covers actor system setup, clustering, persistence, Akka.Management integration, and Aspire orchestration patterns.
Open skill - /akka-best-practices
Critical Akka.NET best practices including EventStream vs DistributedPubSub, supervision strategies, error handling, Props vs DependencyResolver, work distribution patterns, and cluster/local mode abstractions for testability.
Open skill - /akka-hosting-actor-patterns
Patterns for building entity actors with Akka.Hosting - GenericChildPerEntityParent, message extractors, cluster sharding abstraction, akka-reminders, and ITimeProvider. Supports both local testing and clustered production modes.
Open skill - /akka-management
Akka.Management for cluster bootstrapping, service discovery (Kubernetes, Azure, Config), health checks, and dynamic cluster formation without static seed nodes.
Open skill - /akka-testing-patterns
Write unit and integration tests for Akka.NET actors using modern Akka.Hosting.TestKit patterns. Covers dependency injection, TestProbes, persistence testing, and actor interaction verification. Includes guidance on when to use traditional TestKit.
Open skill - /aspire-configuration
Configure Aspire AppHost to emit explicit app config via environment variables; keep app code free of Aspire clients and service discovery.
Open skill

