@mofaggolhoshen/dev-assist-mcp 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/AGENTS.md +72 -0
  2. package/README.md +204 -52
  3. package/content/concepts/circuit-breaker.md +25 -0
  4. package/content/setups/jwt-dotnet9.md +18 -0
  5. package/content/setups/jwt.md +25 -0
  6. package/content/templates/clean-architecture.md +25 -0
  7. package/dist/content/snippetSchema.js +39 -0
  8. package/dist/index.js +8 -0
  9. package/dist/schemas/markdownKnowledge.js +30 -0
  10. package/dist/shared/response.js +12 -0
  11. package/dist/storage/markdownKnowledgeStore.js +267 -0
  12. package/dist/tools/knowledge/explainConcept.js +46 -0
  13. package/dist/tools/knowledge/generateSetup.js +46 -0
  14. package/dist/tools/knowledge/getSnippet.js +52 -39
  15. package/dist/tools/knowledge/getTemplate.js +46 -0
  16. package/dist/tools/knowledge/index.js +4 -0
  17. package/dist/tools/knowledge/searchSnippet.js +56 -0
  18. package/examples/basic-search/README.md +13 -0
  19. package/examples/claude-desktop/README.md +10 -0
  20. package/examples/claude-desktop/claude_desktop_config.json +8 -0
  21. package/examples/cursor/README.md +15 -0
  22. package/examples/explain-mode/expected-response.md +16 -0
  23. package/examples/jwt-setup/expected-response.json +16 -0
  24. package/examples/polly-retry/expected-response.json +14 -0
  25. package/package.json +17 -2
  26. package/scripts/.gitkeep +0 -0
  27. package/snippets/architecture/.gitkeep +0 -0
  28. package/snippets/architecture/clean-architecture-api.md +25 -0
  29. package/snippets/architecture/cqrs-starter.md +25 -0
  30. package/snippets/architecture/ddd-aggregate.md +25 -0
  31. package/snippets/architecture/efcore-repository.md +39 -0
  32. package/snippets/auth/.gitkeep +0 -0
  33. package/snippets/auth/jwe-setup.md +28 -0
  34. package/snippets/auth/jwt-setup-dotnet9.md +27 -0
  35. package/snippets/auth/jwt-setup.md +44 -0
  36. package/snippets/auth/refresh-token-rotation.md +27 -0
  37. package/snippets/auth/role-based-authorization.md +28 -0
  38. package/snippets/caching/.gitkeep +0 -0
  39. package/snippets/caching/cache-aside-pattern.md +25 -0
  40. package/snippets/caching/redis-distributed-cache.md +25 -0
  41. package/snippets/logging/.gitkeep +0 -0
  42. package/snippets/logging/opentelemetry-tracing.md +25 -0
  43. package/snippets/logging/serilog-bootstrap.md +25 -0
  44. package/snippets/logging/structured-logging-guidelines.md +27 -0
  45. package/snippets/messaging/.gitkeep +0 -0
  46. package/snippets/messaging/masstransit-rabbitmq.md +25 -0
  47. package/snippets/messaging/outbox-pattern.md +25 -0
  48. package/snippets/messaging/saga-state-machine.md +25 -0
  49. package/snippets/resilience/.gitkeep +0 -0
  50. package/snippets/resilience/bulkhead-isolation.md +25 -0
  51. package/snippets/resilience/circuit-breaker-polly.md +25 -0
  52. package/snippets/resilience/fallback-policy-polly.md +25 -0
  53. package/snippets/resilience/polly-retry.md +31 -0
  54. package/snippets/resilience/timeout-policy-polly.md +25 -0
  55. package/snippets/efcore-repository.json +0 -7
  56. package/snippets/jwt-setup.json +0 -7
  57. package/snippets/polly-retry.json +0 -7
@@ -0,0 +1,14 @@
1
+ {
2
+ "total": 1,
3
+ "results": [
4
+ {
5
+ "id": "polly-retry",
6
+ "title": "Polly Retry Policy",
7
+ "category": "resilience",
8
+ "framework": "dotnet",
9
+ "confidence": "high",
10
+ "rankScore": 0.82,
11
+ "reasons": ["title_match", "tag_matches:3"]
12
+ }
13
+ ]
14
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mofaggolhoshen/dev-assist-mcp",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -15,7 +15,20 @@
15
15
  "dev": "tsx src/index.ts",
16
16
  "test": "jest"
17
17
  },
18
- "keywords": [],
18
+ "keywords": [
19
+ "mcp",
20
+ "model-context-protocol",
21
+ "developer-tools",
22
+ "ai",
23
+ "copilot",
24
+ "snippets",
25
+ "aspnet",
26
+ "dotnet",
27
+ "csharp",
28
+ "knowledge-base",
29
+ "code-generation",
30
+ "dev-assist"
31
+ ],
19
32
  "author": "",
20
33
  "license": "ISC",
21
34
  "repository": {
@@ -29,7 +42,9 @@
29
42
  "type": "module",
30
43
  "dependencies": {
31
44
  "@modelcontextprotocol/sdk": "^1.29.0",
45
+ "fuse.js": "^7.3.0",
32
46
  "glob": "^13.0.6",
47
+ "gray-matter": "^4.0.3",
33
48
  "zod": "^4.3.6",
34
49
  "zod-to-json-schema": "^3.25.2"
35
50
  },
File without changes
File without changes
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: clean-architecture-api
3
+ title: Clean Architecture API Composition
4
+ summary: Compose API, application, domain, and infrastructure layers.
5
+ framework: dotnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: architecture
9
+ tags:
10
+ - clean-architecture
11
+ - layering
12
+ - api
13
+ difficulty: medium
14
+ bestPractices:
15
+ - Keep dependency flow inward only
16
+ - Register infrastructure implementations in composition root
17
+ pitfalls:
18
+ - Leaking EF entities into API contract layer
19
+ ---
20
+
21
+ ## Implementation
22
+
23
+ ```csharp
24
+ // Configure service registrations at startup by layer.
25
+ ```
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: cqrs-starter
3
+ title: CQRS Starter Pattern
4
+ summary: Separate command and query models for clearer responsibilities.
5
+ framework: dotnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: architecture
9
+ tags:
10
+ - cqrs
11
+ - architecture
12
+ - mediator
13
+ difficulty: medium
14
+ bestPractices:
15
+ - Keep commands side-effect focused
16
+ - Keep queries read-optimized and idempotent
17
+ pitfalls:
18
+ - Applying CQRS to trivial CRUD adds complexity
19
+ ---
20
+
21
+ ## Implementation
22
+
23
+ ```csharp
24
+ // Define CreateOrderCommand and GetOrderByIdQuery handlers separately.
25
+ ```
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: ddd-aggregate
3
+ title: DDD Aggregate Root Rules
4
+ summary: Enforce domain invariants through aggregate boundaries.
5
+ framework: dotnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: architecture
9
+ tags:
10
+ - ddd
11
+ - aggregate
12
+ - domain-model
13
+ difficulty: advanced
14
+ bestPractices:
15
+ - Expose behavior methods rather than setters
16
+ - Keep invariants inside aggregate root
17
+ pitfalls:
18
+ - Directly mutating child entities from outside aggregate
19
+ ---
20
+
21
+ ## Implementation
22
+
23
+ ```csharp
24
+ // Aggregate root methods validate invariants before state changes.
25
+ ```
@@ -0,0 +1,39 @@
1
+ ---
2
+ id: efcore-repository
3
+ title: EF Core Repository Pattern
4
+ summary: Simple EF Core repository with asynchronous read and write operations.
5
+ framework: dotnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: architecture
9
+ tags:
10
+ - efcore
11
+ - repository
12
+ - data-access
13
+ - pattern
14
+ - async
15
+ difficulty: beginner
16
+ bestPractices:
17
+ - Pass CancellationToken through all async database calls
18
+ - Use constructor injection for testability and clear dependencies
19
+ - Keep repositories focused on a single aggregate root
20
+ pitfalls:
21
+ - Avoid exposing IQueryable from the repository to prevent leaky abstractions
22
+ - Calling SaveChangesAsync in every method prevents batching opportunities
23
+ ---
24
+
25
+ ## Implementation
26
+
27
+ ```csharp
28
+ public sealed class ProductRepository(AppDbContext db)
29
+ {
30
+ public Task<Product?> GetByIdAsync(Guid id, CancellationToken ct = default) =>
31
+ db.Products.FirstOrDefaultAsync(p => p.Id == id, ct);
32
+
33
+ public async Task AddAsync(Product entity, CancellationToken ct = default)
34
+ {
35
+ await db.Products.AddAsync(entity, ct);
36
+ await db.SaveChangesAsync(ct);
37
+ }
38
+ }
39
+ ```
File without changes
@@ -0,0 +1,28 @@
1
+ ---
2
+ id: jwe-setup
3
+ title: JWE Encryption Setup (ASP.NET Core)
4
+ summary: Add encrypted JWT (JWE) support for sensitive claims.
5
+ framework: aspnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: auth
9
+ tags:
10
+ - jwe
11
+ - jwt
12
+ - encryption
13
+ - security
14
+ difficulty: advanced
15
+ bestPractices:
16
+ - Encrypt tokens when claims contain sensitive data
17
+ - Separate signing and encryption keys
18
+ pitfalls:
19
+ - Reusing one key for all purposes weakens security
20
+ securityNotes:
21
+ - Store encryption keys in secure vaults and rotate regularly
22
+ ---
23
+
24
+ ## Implementation
25
+
26
+ ```csharp
27
+ // Configure token encryption credentials and validation handlers.
28
+ ```
@@ -0,0 +1,27 @@
1
+ ---
2
+ id: jwt-setup-dotnet9
3
+ title: JWT Setup (.NET 9)
4
+ summary: JWT bearer configuration optimized for ASP.NET on .NET 9.
5
+ updatedAt: 2026-05-10T00:00:00.000Z
6
+ framework: aspnet
7
+ version: .net9
8
+ language: csharp
9
+ category: auth
10
+ tags:
11
+ - jwt
12
+ - authentication
13
+ - dotnet9
14
+ difficulty: medium
15
+ bestPractices:
16
+ - Keep token validation settings explicit
17
+ pitfalls:
18
+ - Disabling issuer/audience checks for convenience
19
+ securityNotes:
20
+ - Keep signing keys in secure secret stores
21
+ ---
22
+
23
+ ## Implementation
24
+
25
+ ```csharp
26
+ // .NET 9 JWT setup baseline
27
+ ```
@@ -0,0 +1,44 @@
1
+ ---
2
+ id: jwt-setup
3
+ title: JWT Authentication Setup (ASP.NET Core)
4
+ summary: Configures JWT bearer authentication with token validation parameters.
5
+ framework: aspnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: auth
9
+ tags:
10
+ - jwt
11
+ - authentication
12
+ - bearer
13
+ - aspnet
14
+ - security
15
+ difficulty: medium
16
+ bestPractices:
17
+ - Always validate issuer and audience to prevent token misuse
18
+ - Store signing keys in environment variables or a secrets manager
19
+ - Use short-lived access tokens with refresh token rotation
20
+ pitfalls:
21
+ - Omitting audience or issuer validation opens the server to token substitution attacks
22
+ - Using a weak or short signing key reduces security
23
+ securityNotes:
24
+ - Signing keys for HS256 should be at least 32 bytes
25
+ - Use HTTPS exclusively to protect bearer tokens in transit
26
+ ---
27
+
28
+ ## Implementation
29
+
30
+ ```csharp
31
+ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
32
+ .AddJwtBearer(options =>
33
+ {
34
+ options.TokenValidationParameters = new TokenValidationParameters
35
+ {
36
+ ValidateIssuer = true,
37
+ ValidateAudience = true,
38
+ ValidateIssuerSigningKey = true,
39
+ ValidIssuer = config["Jwt:Issuer"],
40
+ ValidAudience = config["Jwt:Audience"],
41
+ IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config["Jwt:Key"]!))
42
+ };
43
+ });
44
+ ```
@@ -0,0 +1,27 @@
1
+ ---
2
+ id: refresh-token-rotation
3
+ title: Refresh Token Rotation
4
+ summary: Secure refresh flow that invalidates tokens after each use.
5
+ framework: aspnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: auth
9
+ tags:
10
+ - refresh-token
11
+ - auth
12
+ - security
13
+ difficulty: medium
14
+ bestPractices:
15
+ - Rotate refresh tokens on every successful exchange
16
+ - Track token family and revoke on reuse detection
17
+ pitfalls:
18
+ - Long-lived reusable refresh tokens increase takeover risk
19
+ securityNotes:
20
+ - Hash refresh tokens before persistence
21
+ ---
22
+
23
+ ## Implementation
24
+
25
+ ```csharp
26
+ // Issue new refresh token and revoke previous token atomically.
27
+ ```
@@ -0,0 +1,28 @@
1
+ ---
2
+ id: role-based-authorization
3
+ title: Role-Based Authorization Policies
4
+ summary: Define policy-based authorization rules using roles and claims.
5
+ framework: aspnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: auth
9
+ tags:
10
+ - authorization
11
+ - roles
12
+ - policies
13
+ difficulty: beginner
14
+ bestPractices:
15
+ - Prefer policies over hardcoded role checks in controllers
16
+ - Keep policy names stable and domain-oriented
17
+ pitfalls:
18
+ - Embedding authorization logic directly in business services
19
+ ---
20
+
21
+ ## Implementation
22
+
23
+ ```csharp
24
+ builder.Services.AddAuthorization(options =>
25
+ {
26
+ options.AddPolicy("CanManageUsers", p => p.RequireRole("Admin"));
27
+ });
28
+ ```
File without changes
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: cache-aside-pattern
3
+ title: Cache-Aside Pattern
4
+ summary: Load from cache first, then source of truth on misses.
5
+ framework: dotnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: caching
9
+ tags:
10
+ - cache-aside
11
+ - caching
12
+ - performance
13
+ difficulty: beginner
14
+ bestPractices:
15
+ - Cache misses should populate cache with sensible expiration
16
+ - Use stale-while-revalidate for hot paths when appropriate
17
+ pitfalls:
18
+ - No eviction strategy causes stale data and memory growth
19
+ ---
20
+
21
+ ## Implementation
22
+
23
+ ```csharp
24
+ // Try cache, fetch DB on miss, then set cache.
25
+ ```
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: redis-distributed-cache
3
+ title: Redis Distributed Cache Setup
4
+ summary: Configure Redis cache provider for shared low-latency data access.
5
+ framework: aspnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: caching
9
+ tags:
10
+ - redis
11
+ - cache
12
+ - distributed
13
+ difficulty: beginner
14
+ bestPractices:
15
+ - Set TTL based on freshness requirements
16
+ - Use namespaced cache keys
17
+ pitfalls:
18
+ - Very large values increase serialization overhead and latency
19
+ ---
20
+
21
+ ## Implementation
22
+
23
+ ```csharp
24
+ // builder.Services.AddStackExchangeRedisCache(...)
25
+ ```
File without changes
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: opentelemetry-tracing
3
+ title: OpenTelemetry Tracing Setup
4
+ summary: Add distributed tracing with ASP.NET and outbound HTTP instrumentation.
5
+ framework: aspnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: logging
9
+ tags:
10
+ - opentelemetry
11
+ - tracing
12
+ - observability
13
+ difficulty: medium
14
+ bestPractices:
15
+ - Propagate trace context across service boundaries
16
+ - Export traces to centralized backend
17
+ pitfalls:
18
+ - Sampling too low during incident response obscures root cause
19
+ ---
20
+
21
+ ## Implementation
22
+
23
+ ```csharp
24
+ // builder.Services.AddOpenTelemetry().WithTracing(...)
25
+ ```
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: serilog-bootstrap
3
+ title: Serilog Bootstrap Logger
4
+ summary: Capture startup exceptions and switch to configured logging pipeline.
5
+ framework: aspnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: logging
9
+ tags:
10
+ - serilog
11
+ - logging
12
+ - startup
13
+ difficulty: beginner
14
+ bestPractices:
15
+ - Initialize bootstrap logger before host build
16
+ - Include correlation ids in enrichers
17
+ pitfalls:
18
+ - Delayed logger init loses early critical errors
19
+ ---
20
+
21
+ ## Implementation
22
+
23
+ ```csharp
24
+ // Log.Logger = new LoggerConfiguration().WriteTo.Console().CreateBootstrapLogger();
25
+ ```
@@ -0,0 +1,27 @@
1
+ ---
2
+ id: structured-logging-guidelines
3
+ title: Structured Logging Guidelines
4
+ summary: Build queryable logs with consistent properties and event ids.
5
+ framework: dotnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: logging
9
+ tags:
10
+ - structured-logging
11
+ - observability
12
+ - serilog
13
+ difficulty: beginner
14
+ bestPractices:
15
+ - Use named properties not interpolated strings
16
+ - Attach tenant, user, and correlation context consistently
17
+ pitfalls:
18
+ - Logging secrets or PII in structured properties
19
+ securityNotes:
20
+ - Redact sensitive data before log emission
21
+ ---
22
+
23
+ ## Implementation
24
+
25
+ ```csharp
26
+ logger.LogInformation("Order created {OrderId} for {CustomerId}", orderId, customerId);
27
+ ```
File without changes
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: masstransit-rabbitmq
3
+ title: MassTransit with RabbitMQ
4
+ summary: Configure message bus, consumers, and retry policies.
5
+ framework: dotnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: messaging
9
+ tags:
10
+ - masstransit
11
+ - rabbitmq
12
+ - messaging
13
+ difficulty: medium
14
+ bestPractices:
15
+ - Use consumer definitions for endpoint consistency
16
+ - Configure retry and dead-letter policies
17
+ pitfalls:
18
+ - Sharing queues across unrelated consumers
19
+ ---
20
+
21
+ ## Implementation
22
+
23
+ ```csharp
24
+ // services.AddMassTransit(x => { ... });
25
+ ```
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: outbox-pattern
3
+ title: Transactional Outbox Pattern
4
+ summary: Ensure reliable event publishing with database consistency.
5
+ framework: dotnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: messaging
9
+ tags:
10
+ - outbox
11
+ - reliability
12
+ - messaging
13
+ difficulty: advanced
14
+ bestPractices:
15
+ - Write outbox records in the same DB transaction as business changes
16
+ - Use background dispatcher with retry and dedupe
17
+ pitfalls:
18
+ - Deleting outbox rows before successful publish acknowledgment
19
+ ---
20
+
21
+ ## Implementation
22
+
23
+ ```csharp
24
+ // Persist integration event to outbox table inside transaction.
25
+ ```
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: saga-state-machine
3
+ title: Saga State Machine Basics
4
+ summary: Coordinate long-running workflows across distributed services.
5
+ framework: dotnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: messaging
9
+ tags:
10
+ - saga
11
+ - state-machine
12
+ - masstransit
13
+ difficulty: advanced
14
+ bestPractices:
15
+ - Persist saga state durably
16
+ - Define timeout and compensation transitions
17
+ pitfalls:
18
+ - Missing idempotency in event handlers causes duplicate effects
19
+ ---
20
+
21
+ ## Implementation
22
+
23
+ ```csharp
24
+ // Define states, events, transitions, and compensation steps.
25
+ ```
File without changes
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: bulkhead-isolation
3
+ title: Bulkhead Isolation for External Calls
4
+ summary: Limit concurrency to isolate failures in heavy dependencies.
5
+ framework: aspnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: resilience
9
+ tags:
10
+ - bulkhead
11
+ - concurrency
12
+ - resilience
13
+ difficulty: advanced
14
+ bestPractices:
15
+ - Set queue and parallelism based on load tests
16
+ - Protect critical paths with separate bulkheads
17
+ pitfalls:
18
+ - Shared bulkhead for unrelated dependencies causes coupling
19
+ ---
20
+
21
+ ## Implementation
22
+
23
+ ```csharp
24
+ // AddBulkheadPolicy(...) with per-dependency limits.
25
+ ```
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: circuit-breaker-polly
3
+ title: Polly Circuit Breaker
4
+ summary: Fail fast after repeated errors and allow recovery windows.
5
+ framework: aspnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: resilience
9
+ tags:
10
+ - polly
11
+ - circuit-breaker
12
+ - resilience
13
+ difficulty: medium
14
+ bestPractices:
15
+ - Configure thresholds based on service SLOs
16
+ - Combine with retry and timeout policies
17
+ pitfalls:
18
+ - Opening breaker too aggressively can block healthy traffic
19
+ ---
20
+
21
+ ## Implementation
22
+
23
+ ```csharp
24
+ // AddCircuitBreakerAsync(...) on HttpClient policy chain.
25
+ ```
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: fallback-policy-polly
3
+ title: Polly Fallback Policy
4
+ summary: Return controlled fallback responses when dependencies fail.
5
+ framework: aspnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: resilience
9
+ tags:
10
+ - polly
11
+ - fallback
12
+ - resilience
13
+ difficulty: medium
14
+ bestPractices:
15
+ - Keep fallback responses explicit and observable
16
+ - Emit logs and metrics when fallback is triggered
17
+ pitfalls:
18
+ - Silent fallback can hide outages from operators
19
+ ---
20
+
21
+ ## Implementation
22
+
23
+ ```csharp
24
+ // AddFallbackAsync(...) with domain-safe default response.
25
+ ```
@@ -0,0 +1,31 @@
1
+ ---
2
+ id: polly-retry
3
+ title: Polly Retry Policy (.NET)
4
+ summary: Configures an HTTP retry policy with exponential backoff using Polly.
5
+ framework: aspnet
6
+ version: .net8+
7
+ language: csharp
8
+ category: resilience
9
+ tags:
10
+ - retry
11
+ - resilience
12
+ - polly
13
+ - http
14
+ - exponential-backoff
15
+ difficulty: medium
16
+ bestPractices:
17
+ - Use exponential backoff to avoid overwhelming a failing service
18
+ - Combine retry with circuit breaker for comprehensive resilience
19
+ - Log each retry attempt for observability
20
+ pitfalls:
21
+ - Avoid retrying non-transient errors such as 400 Bad Request or 401 Unauthorized
22
+ - Do not use a fixed delay in high-concurrency scenarios; exponential backoff with jitter is preferred
23
+ ---
24
+
25
+ ## Implementation
26
+
27
+ ```csharp
28
+ builder.Services.AddHttpClient("MyClient")
29
+ .AddTransientHttpErrorPolicy(p =>
30
+ p.WaitAndRetryAsync(3, attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt))));
31
+ ```