skills/dotnet/patterns/retry-policy/SKILL.md
Define explicit retry policies for handling transient failures in external dependencies in .NET applications. Use when: - Handling transient failures from external services - Implementing resilient service calls - Building systems that need to recover from temporary failures - Implementing circuit breaker patterns - Handling network timeouts and connection issues Triggers: "retry policy", "transient failure", "circuit breaker", "resilience", "exponential backoff", "retry logic"
npx skillsauth add yeeehaooo/WorkSpace retry-policyInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Define explicit retry policies for handling transient failures in external dependencies.
Applies to:
// Application Layer
public interface IRetryPolicy
{
Task<T> ExecuteAsync<T>(Func<Task<T>> operation, CancellationToken ct = default);
Task ExecuteAsync(Func<Task> operation, CancellationToken ct = default);
}
public enum RetryableExceptionType
{
NetworkError,
Timeout,
ServiceUnavailable
}
// Infrastructure Layer
public class ExponentialBackoffRetryPolicy : IRetryPolicy
{
private readonly int _maxRetries;
private readonly TimeSpan _initialDelay;
private readonly double _backoffMultiplier;
private readonly ILogger<ExponentialBackoffRetryPolicy> _logger;
public ExponentialBackoffRetryPolicy(
int maxRetries = 3,
TimeSpan? initialDelay = null,
double backoffMultiplier = 2.0,
ILogger<ExponentialBackoffRetryPolicy>? logger = null)
{
_maxRetries = maxRetries;
_initialDelay = initialDelay ?? TimeSpan.FromSeconds(1);
_backoffMultiplier = backoffMultiplier;
_logger = logger;
}
public async Task<T> ExecuteAsync<T>(Func<Task<T>> operation, CancellationToken ct = default)
{
var delay = _initialDelay;
for (int attempt = 0; attempt <= _maxRetries; attempt++)
{
try
{
return await operation();
}
catch (Exception ex) when (IsRetryable(ex) && attempt < _maxRetries)
{
_logger?.LogWarning(
ex,
"Operation failed (attempt {Attempt}/{MaxRetries}), retrying in {DelayMs}ms",
attempt + 1, _maxRetries + 1, delay.TotalMilliseconds);
await Task.Delay(delay, ct);
delay = TimeSpan.FromMilliseconds(delay.TotalMilliseconds * _backoffMultiplier);
}
}
// Last attempt failed, throw exception
return await operation();
}
public async Task ExecuteAsync(Func<Task> operation, CancellationToken ct = default)
{
await ExecuteAsync(async () => { await operation(); return 0; }, ct);
}
private bool IsRetryable(Exception ex)
{
return ex is HttpRequestException ||
ex is TaskCanceledException ||
ex is TimeoutException ||
(ex is HttpRequestException httpEx &&
(httpEx.Message.Contains("timeout") ||
httpEx.Message.Contains("connection")));
}
}
// Usage
public class ExternalApiService
{
private readonly IRetryPolicy _retryPolicy;
private readonly HttpClient _httpClient;
public async Task<ApiResponse> CallExternalApiAsync(string endpoint, CancellationToken ct = default)
{
return await _retryPolicy.ExecuteAsync(async () =>
{
var response = await _httpClient.GetAsync(endpoint, ct);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync(ct);
return JsonSerializer.Deserialize<ApiResponse>(content)!;
}, ct);
}
}
development
Create reusable .NET atomic capability code snippets that can be directly copied and pasted. Use when: - Creating single-purpose code snippets - Building reusable code templates - Implementing atomic technical capabilities - Creating copy-pasteable code blocks - Building snippet library for common patterns Triggers: "create snippet", "code snippet", "reusable snippet", "atomic snippet", "copy-paste code"
development
Create Docker Compose configuration for containerized .NET application development and deployment. Use when: - Containerizing .NET applications - Setting up local development environment with dependencies - Creating multi-container setups (API + DB + Redis) - Defining service dependencies and networking - Building docker-compose.yml for development or production Triggers: "docker compose", "containerize", "multi-container", "docker-compose.yml", "docker setup"
tools
Create adapter structure for integrating third-party APIs in Clean Architecture applications. Use when: - Integrating external APIs or services - Creating HTTP client adapters for third-party services - Implementing API integration with error handling - Setting up adapter pattern for external dependencies - Building resilient external service integrations Triggers: "api adapter", "third-party api", "external service", "http client adapter", "api integration"
development
Enterprise backend structure built on Clean Architecture, DDD, CQRS, and Vertical Slice API Design with Dapper-first persistence. Use when: - Creating new enterprise backend projects - Implementing Clean Architecture with DDD and CQRS - Building vertical slice API endpoints - Using Dapper as primary persistence mechanism - Organizing modules by UseCase-driven and Model-driven separation Triggers: "dmis structure", "clean architecture", "enterprise backend", "DDD CQRS", "vertical slice", "dapper"