mvp24hours-dotnet-mcp 1.0.0

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.

Potentially problematic release.


This version of mvp24hours-dotnet-mcp might be problematic. Click here for more details.

Files changed (214) hide show
  1. package/CONTRIBUTING.md +217 -0
  2. package/LICENSE +21 -0
  3. package/README.md +221 -0
  4. package/dist/index.d.ts +10 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +1454 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/tools/ai-implementation.d.ts +28 -0
  9. package/dist/tools/ai-implementation.d.ts.map +1 -0
  10. package/dist/tools/ai-implementation.js +1251 -0
  11. package/dist/tools/ai-implementation.js.map +1 -0
  12. package/dist/tools/architecture-advisor.d.ts +42 -0
  13. package/dist/tools/architecture-advisor.d.ts.map +1 -0
  14. package/dist/tools/architecture-advisor.js +442 -0
  15. package/dist/tools/architecture-advisor.js.map +1 -0
  16. package/dist/tools/containerization-patterns.d.ts +18 -0
  17. package/dist/tools/containerization-patterns.d.ts.map +1 -0
  18. package/dist/tools/containerization-patterns.js +819 -0
  19. package/dist/tools/containerization-patterns.js.map +1 -0
  20. package/dist/tools/core-patterns.d.ts +18 -0
  21. package/dist/tools/core-patterns.d.ts.map +1 -0
  22. package/dist/tools/core-patterns.js +1039 -0
  23. package/dist/tools/core-patterns.js.map +1 -0
  24. package/dist/tools/cqrs-guide.d.ts +18 -0
  25. package/dist/tools/cqrs-guide.d.ts.map +1 -0
  26. package/dist/tools/cqrs-guide.js +2777 -0
  27. package/dist/tools/cqrs-guide.js.map +1 -0
  28. package/dist/tools/database-advisor.d.ts +39 -0
  29. package/dist/tools/database-advisor.d.ts.map +1 -0
  30. package/dist/tools/database-advisor.js +598 -0
  31. package/dist/tools/database-advisor.js.map +1 -0
  32. package/dist/tools/get-started.d.ts +20 -0
  33. package/dist/tools/get-started.d.ts.map +1 -0
  34. package/dist/tools/get-started.js +254 -0
  35. package/dist/tools/get-started.js.map +1 -0
  36. package/dist/tools/get-template.d.ts +17 -0
  37. package/dist/tools/get-template.d.ts.map +1 -0
  38. package/dist/tools/get-template.js +605 -0
  39. package/dist/tools/get-template.js.map +1 -0
  40. package/dist/tools/infrastructure-guide.d.ts +18 -0
  41. package/dist/tools/infrastructure-guide.d.ts.map +1 -0
  42. package/dist/tools/infrastructure-guide.js +1078 -0
  43. package/dist/tools/infrastructure-guide.js.map +1 -0
  44. package/dist/tools/messaging-patterns.d.ts +18 -0
  45. package/dist/tools/messaging-patterns.d.ts.map +1 -0
  46. package/dist/tools/messaging-patterns.js +718 -0
  47. package/dist/tools/messaging-patterns.js.map +1 -0
  48. package/dist/tools/modernization-guide.d.ts +23 -0
  49. package/dist/tools/modernization-guide.d.ts.map +1 -0
  50. package/dist/tools/modernization-guide.js +1072 -0
  51. package/dist/tools/modernization-guide.js.map +1 -0
  52. package/dist/tools/observability-setup.d.ts +23 -0
  53. package/dist/tools/observability-setup.d.ts.map +1 -0
  54. package/dist/tools/observability-setup.js +592 -0
  55. package/dist/tools/observability-setup.js.map +1 -0
  56. package/dist/tools/reference-guide.d.ts +18 -0
  57. package/dist/tools/reference-guide.d.ts.map +1 -0
  58. package/dist/tools/reference-guide.js +890 -0
  59. package/dist/tools/reference-guide.js.map +1 -0
  60. package/dist/tools/security-patterns.d.ts +18 -0
  61. package/dist/tools/security-patterns.d.ts.map +1 -0
  62. package/dist/tools/security-patterns.js +898 -0
  63. package/dist/tools/security-patterns.js.map +1 -0
  64. package/dist/tools/testing-patterns.d.ts +18 -0
  65. package/dist/tools/testing-patterns.d.ts.map +1 -0
  66. package/dist/tools/testing-patterns.js +1151 -0
  67. package/dist/tools/testing-patterns.js.map +1 -0
  68. package/dist/utils/doc-loader.d.ts +28 -0
  69. package/dist/utils/doc-loader.d.ts.map +1 -0
  70. package/dist/utils/doc-loader.js +88 -0
  71. package/dist/utils/doc-loader.js.map +1 -0
  72. package/docs/ai-context/ai-decision-matrix.md +216 -0
  73. package/docs/ai-context/ai-implementation-index.md +333 -0
  74. package/docs/ai-context/api-versioning-patterns.md +597 -0
  75. package/docs/ai-context/architecture-templates.md +794 -0
  76. package/docs/ai-context/containerization-patterns.md +633 -0
  77. package/docs/ai-context/database-patterns.md +575 -0
  78. package/docs/ai-context/decision-matrix.md +329 -0
  79. package/docs/ai-context/error-handling-patterns.md +727 -0
  80. package/docs/ai-context/home.md +298 -0
  81. package/docs/ai-context/messaging-patterns.md +547 -0
  82. package/docs/ai-context/modernization-patterns.md +756 -0
  83. package/docs/ai-context/observability-patterns.md +594 -0
  84. package/docs/ai-context/project-structure.md +264 -0
  85. package/docs/ai-context/security-patterns.md +662 -0
  86. package/docs/ai-context/structure-complex-nlayers.md +982 -0
  87. package/docs/ai-context/structure-minimal-api.md +668 -0
  88. package/docs/ai-context/structure-simple-nlayers.md +754 -0
  89. package/docs/ai-context/template-agent-framework-basic.md +1159 -0
  90. package/docs/ai-context/template-agent-framework-middleware.md +519 -0
  91. package/docs/ai-context/template-agent-framework-multi-agent.md +1187 -0
  92. package/docs/ai-context/template-agent-framework-workflows.md +1234 -0
  93. package/docs/ai-context/template-clean-architecture.md +858 -0
  94. package/docs/ai-context/template-cqrs.md +938 -0
  95. package/docs/ai-context/template-ddd.md +1053 -0
  96. package/docs/ai-context/template-event-driven.md +884 -0
  97. package/docs/ai-context/template-hexagonal.md +922 -0
  98. package/docs/ai-context/template-microservices.md +788 -0
  99. package/docs/ai-context/template-sk-chat-completion.md +816 -0
  100. package/docs/ai-context/template-sk-planners.md +859 -0
  101. package/docs/ai-context/template-sk-plugins.md +793 -0
  102. package/docs/ai-context/template-sk-rag-basic.md +890 -0
  103. package/docs/ai-context/template-skg-chain-of-thought.md +981 -0
  104. package/docs/ai-context/template-skg-chatbot-memory.md +785 -0
  105. package/docs/ai-context/template-skg-checkpointing.md +1314 -0
  106. package/docs/ai-context/template-skg-document-pipeline.md +1110 -0
  107. package/docs/ai-context/template-skg-graph-executor.md +777 -0
  108. package/docs/ai-context/template-skg-human-in-loop.md +1179 -0
  109. package/docs/ai-context/template-skg-multi-agent.md +901 -0
  110. package/docs/ai-context/template-skg-observability.md +1020 -0
  111. package/docs/ai-context/template-skg-react-agent.md +742 -0
  112. package/docs/ai-context/template-skg-streaming.md +930 -0
  113. package/docs/ai-context/testing-patterns.md +715 -0
  114. package/docs/application-services.md +883 -0
  115. package/docs/broker-advanced.md +738 -0
  116. package/docs/broker.md +188 -0
  117. package/docs/caching-advanced.md +666 -0
  118. package/docs/core/entity-interfaces.md +412 -0
  119. package/docs/core/exceptions.md +439 -0
  120. package/docs/core/functional-patterns.md +382 -0
  121. package/docs/core/guard-clauses.md +385 -0
  122. package/docs/core/home.md +109 -0
  123. package/docs/core/infrastructure-abstractions.md +386 -0
  124. package/docs/core/smart-enums.md +327 -0
  125. package/docs/core/strongly-typed-ids.md +352 -0
  126. package/docs/core/value-objects.md +356 -0
  127. package/docs/cqrs/api-reference.md +433 -0
  128. package/docs/cqrs/behaviors.md +215 -0
  129. package/docs/cqrs/best-practices.md +300 -0
  130. package/docs/cqrs/commands.md +267 -0
  131. package/docs/cqrs/concepts-comparison.md +208 -0
  132. package/docs/cqrs/domain-events.md +244 -0
  133. package/docs/cqrs/event-sourcing/aggregate.md +303 -0
  134. package/docs/cqrs/event-sourcing/event-store.md +292 -0
  135. package/docs/cqrs/event-sourcing/home.md +182 -0
  136. package/docs/cqrs/event-sourcing/projections.md +312 -0
  137. package/docs/cqrs/event-sourcing/snapshots.md +316 -0
  138. package/docs/cqrs/extensibility.md +473 -0
  139. package/docs/cqrs/getting-started.md +163 -0
  140. package/docs/cqrs/home.md +81 -0
  141. package/docs/cqrs/integration-caching.md +238 -0
  142. package/docs/cqrs/integration-events.md +257 -0
  143. package/docs/cqrs/integration-rabbitmq.md +304 -0
  144. package/docs/cqrs/integration-repository.md +235 -0
  145. package/docs/cqrs/integration-unitofwork.md +224 -0
  146. package/docs/cqrs/mediator.md +232 -0
  147. package/docs/cqrs/migration-mediatr.md +304 -0
  148. package/docs/cqrs/multi-tenancy.md +473 -0
  149. package/docs/cqrs/notifications.md +234 -0
  150. package/docs/cqrs/observability/audit.md +300 -0
  151. package/docs/cqrs/observability/telemetry.md +290 -0
  152. package/docs/cqrs/observability/tracing.md +284 -0
  153. package/docs/cqrs/queries.md +263 -0
  154. package/docs/cqrs/resilience/circuit-breaker.md +341 -0
  155. package/docs/cqrs/resilience/idempotency.md +200 -0
  156. package/docs/cqrs/resilience/inbox-outbox.md +450 -0
  157. package/docs/cqrs/resilience/retry.md +238 -0
  158. package/docs/cqrs/saga/compensation.md +311 -0
  159. package/docs/cqrs/saga/home.md +199 -0
  160. package/docs/cqrs/saga/implementation.md +422 -0
  161. package/docs/cqrs/scheduled-commands.md +537 -0
  162. package/docs/cqrs/specifications.md +580 -0
  163. package/docs/cqrs/validation-behavior.md +287 -0
  164. package/docs/cronjob-advanced.md +921 -0
  165. package/docs/cronjob-observability.md +369 -0
  166. package/docs/cronjob-resilience.md +378 -0
  167. package/docs/cronjob.md +343 -0
  168. package/docs/database/efcore-advanced.md +765 -0
  169. package/docs/database/mongodb-advanced.md +716 -0
  170. package/docs/database/nosql.md +226 -0
  171. package/docs/database/relational.md +145 -0
  172. package/docs/database/use-context.md +97 -0
  173. package/docs/database/use-entity.md +72 -0
  174. package/docs/database/use-repository.md +120 -0
  175. package/docs/database/use-service.md +58 -0
  176. package/docs/database/use-unitofwork.md +34 -0
  177. package/docs/documentation.md +186 -0
  178. package/docs/getting-started.md +163 -0
  179. package/docs/home.md +76 -0
  180. package/docs/index.md +175 -0
  181. package/docs/logging.md +301 -0
  182. package/docs/mapping.md +163 -0
  183. package/docs/migration.md +411 -0
  184. package/docs/modernization/aspire.md +393 -0
  185. package/docs/modernization/channels.md +440 -0
  186. package/docs/modernization/dotnet9-features.md +281 -0
  187. package/docs/modernization/generic-resilience.md +373 -0
  188. package/docs/modernization/http-resilience.md +250 -0
  189. package/docs/modernization/hybrid-cache.md +431 -0
  190. package/docs/modernization/keyed-services.md +383 -0
  191. package/docs/modernization/migration-guide.md +657 -0
  192. package/docs/modernization/minimal-apis.md +407 -0
  193. package/docs/modernization/native-openapi.md +426 -0
  194. package/docs/modernization/options-configuration.md +404 -0
  195. package/docs/modernization/output-caching.md +454 -0
  196. package/docs/modernization/periodic-timer.md +315 -0
  197. package/docs/modernization/problem-details.md +432 -0
  198. package/docs/modernization/rate-limiting.md +385 -0
  199. package/docs/modernization/source-generators.md +219 -0
  200. package/docs/modernization/time-provider.md +303 -0
  201. package/docs/observability/exporters.md +556 -0
  202. package/docs/observability/home.md +186 -0
  203. package/docs/observability/logging.md +589 -0
  204. package/docs/observability/metrics.md +504 -0
  205. package/docs/observability/migration.md +337 -0
  206. package/docs/observability/tracing.md +453 -0
  207. package/docs/pipeline.md +383 -0
  208. package/docs/release.md +253 -0
  209. package/docs/specification.md +130 -0
  210. package/docs/telemetry.md +189 -0
  211. package/docs/validation.md +205 -0
  212. package/docs/webapi-advanced.md +1188 -0
  213. package/docs/webapi.md +401 -0
  214. package/package.json +68 -0
@@ -0,0 +1,454 @@
1
+ # Output Caching - ASP.NET Core Native Server-Side Caching
2
+
3
+ ## Overview
4
+
5
+ **Output Caching** is a server-side caching mechanism introduced in .NET 7 that stores complete HTTP responses on the server and serves them directly without re-executing endpoint logic. Unlike Response Caching (which relies on HTTP cache headers), Output Caching is entirely server-controlled.
6
+
7
+ ## Key Features
8
+
9
+ | Feature | Response Caching | Output Caching |
10
+ |---------|------------------|----------------|
11
+ | Cache Location | Client/Proxy (HTTP headers) | Server-side |
12
+ | Control | HTTP Cache-Control headers | Server policies |
13
+ | Invalidation | Limited (time-based) | ✅ Tag-based programmatic |
14
+ | Distributed Support | ❌ | ✅ Redis backend |
15
+ | Policy-based | ❌ | ✅ Named policies |
16
+ | Vary Support | Limited | ✅ Query, Header, Route |
17
+
18
+ ## Getting Started
19
+
20
+ ### Basic Setup (In-Memory)
21
+
22
+ ```csharp
23
+ // Program.cs
24
+ builder.Services.AddMvp24HoursOutputCache();
25
+
26
+ var app = builder.Build();
27
+
28
+ app.UseRouting();
29
+ app.UseMvp24HoursOutputCache();
30
+ app.MapControllers();
31
+ ```
32
+
33
+ ### With Standard Policies
34
+
35
+ ```csharp
36
+ builder.Services.AddMvp24HoursOutputCache(options =>
37
+ {
38
+ options.DefaultExpirationTimeSpan = TimeSpan.FromMinutes(5);
39
+ options.AddStandardPolicies(); // Adds: Default, Short, Medium, Long, NoCache
40
+ });
41
+ ```
42
+
43
+ ### With Redis Backend (Distributed)
44
+
45
+ ```csharp
46
+ // For multi-instance deployments
47
+ builder.Services.AddMvp24HoursOutputCacheWithRedis(
48
+ "localhost:6379",
49
+ options =>
50
+ {
51
+ options.AddStandardPolicies();
52
+ options.RedisInstanceName = "myapp:oc:";
53
+ });
54
+ ```
55
+
56
+ ## Named Policies
57
+
58
+ Mvp24Hours provides several preset policies:
59
+
60
+ | Policy | Duration | Use Case |
61
+ |--------|----------|----------|
62
+ | `NoCache` | None | Disable caching |
63
+ | `Short` | 1 minute | Frequently changing data |
64
+ | `Medium` | 10 minutes | Moderately changing data |
65
+ | `Long` | 1 hour | Rarely changing data |
66
+ | `VeryLong` | 24 hours | Static content |
67
+ | `Authenticated` | 5 minutes | User-specific data (varies by Authorization) |
68
+ | `Api` | 5 minutes | API responses (varies by Accept header) |
69
+
70
+ ### Using Policies with Minimal APIs
71
+
72
+ ```csharp
73
+ // Using named policy
74
+ app.MapGet("/products", GetProducts)
75
+ .CacheOutput("Medium");
76
+
77
+ // Using Mvp24Hours extension
78
+ app.MapGet("/products", GetProducts)
79
+ .CacheOutputWithPolicy("Medium");
80
+
81
+ // Inline configuration
82
+ app.MapGet("/products", GetProducts)
83
+ .CacheOutputFor(
84
+ TimeSpan.FromMinutes(5),
85
+ tags: new[] { "products" },
86
+ varyByQuery: new[] { "category", "page" });
87
+
88
+ // Disable caching
89
+ app.MapPost("/orders", CreateOrder)
90
+ .NoCacheOutput();
91
+ ```
92
+
93
+ ### Using Policies with Controllers
94
+
95
+ ```csharp
96
+ [ApiController]
97
+ [Route("api/[controller]")]
98
+ public class ProductsController : ControllerBase
99
+ {
100
+ // Use named policy
101
+ [HttpGet]
102
+ [OutputCache(PolicyName = "Medium")]
103
+ public async Task<IActionResult> GetAll()
104
+ {
105
+ // ...
106
+ }
107
+
108
+ // Custom configuration
109
+ [HttpGet("{id}")]
110
+ [OutputCache(Duration = 60, VaryByRouteValueNames = new[] { "id" })]
111
+ public async Task<IActionResult> GetById(int id)
112
+ {
113
+ // ...
114
+ }
115
+
116
+ // Disable caching
117
+ [HttpPost]
118
+ [OutputCache(NoStore = true)]
119
+ public async Task<IActionResult> Create([FromBody] ProductDto dto)
120
+ {
121
+ // ...
122
+ }
123
+ }
124
+ ```
125
+
126
+ ## Custom Policies
127
+
128
+ ### Creating Named Policies
129
+
130
+ ```csharp
131
+ builder.Services.AddMvp24HoursOutputCache(options =>
132
+ {
133
+ // Products policy with tags for selective invalidation
134
+ options.AddPolicy("Products", p => p
135
+ .Expire(TimeSpan.FromMinutes(10))
136
+ .SetTags("products", "catalog")
137
+ .SetVaryByQuery("category", "page", "sort"));
138
+
139
+ // User-specific content
140
+ options.AddPolicy("UserProfile", p => p
141
+ .Expire(TimeSpan.FromMinutes(5))
142
+ .SetVaryByHeader("Authorization")
143
+ .SetTags("users")
144
+ .AllowAuthenticatedRequests());
145
+
146
+ // Search results with all query parameters
147
+ options.AddPolicy("Search", p => p
148
+ {
149
+ p.ExpirationTimeSpan = TimeSpan.FromMinutes(2);
150
+ p.VaryByAllQueryKeys = true;
151
+ p.Tags.Add("search");
152
+ });
153
+
154
+ // Localized content
155
+ options.AddPolicy("Localized", p => p
156
+ .Expire(TimeSpan.FromHours(1))
157
+ .SetVaryByHeader("Accept-Language")
158
+ .SetTags("content"));
159
+ });
160
+ ```
161
+
162
+ ## Cache Invalidation
163
+
164
+ ### Tag-based Invalidation
165
+
166
+ Output Caching supports tag-based invalidation through `IOutputCacheInvalidator`:
167
+
168
+ ```csharp
169
+ public class ProductService
170
+ {
171
+ private readonly IProductRepository _repository;
172
+ private readonly IOutputCacheInvalidator _cacheInvalidator;
173
+
174
+ public ProductService(
175
+ IProductRepository repository,
176
+ IOutputCacheInvalidator cacheInvalidator)
177
+ {
178
+ _repository = repository;
179
+ _cacheInvalidator = cacheInvalidator;
180
+ }
181
+
182
+ public async Task<Product> CreateProductAsync(ProductDto dto)
183
+ {
184
+ var product = await _repository.CreateAsync(dto);
185
+
186
+ // Invalidate all product-related cache entries
187
+ await _cacheInvalidator.EvictByTagAsync("products");
188
+
189
+ return product;
190
+ }
191
+
192
+ public async Task UpdateProductAsync(int id, ProductDto dto)
193
+ {
194
+ await _repository.UpdateAsync(id, dto);
195
+
196
+ // Invalidate specific product and general product list
197
+ await _cacheInvalidator.EvictByTagsAsync(new[]
198
+ {
199
+ "products",
200
+ $"product:{id}"
201
+ });
202
+ }
203
+ }
204
+ ```
205
+
206
+ ### Using with CQRS Commands
207
+
208
+ ```csharp
209
+ public class CreateProductCommandHandler : ICommandHandler<CreateProductCommand, Product>
210
+ {
211
+ private readonly IProductRepository _repository;
212
+ private readonly IOutputCacheInvalidator _cacheInvalidator;
213
+
214
+ public async Task<Product> Handle(
215
+ CreateProductCommand command,
216
+ CancellationToken cancellationToken)
217
+ {
218
+ var product = await _repository.CreateAsync(command.Data);
219
+
220
+ // Invalidate cache after successful command
221
+ await _cacheInvalidator.EvictByTagAsync("products", cancellationToken);
222
+
223
+ return product;
224
+ }
225
+ }
226
+ ```
227
+
228
+ ## Vary-By Strategies
229
+
230
+ ### Vary By Query String
231
+
232
+ ```csharp
233
+ // Vary by specific keys
234
+ options.AddPolicy("Search", p => p
235
+ .SetVaryByQuery("q", "page", "size")
236
+ .Expire(TimeSpan.FromMinutes(2)));
237
+
238
+ // Vary by all query keys
239
+ options.AddPolicy("DynamicSearch", p => p
240
+ {
241
+ p.VaryByAllQueryKeys = true;
242
+ p.ExpirationTimeSpan = TimeSpan.FromMinutes(2);
243
+ });
244
+ ```
245
+
246
+ ### Vary By Header
247
+
248
+ ```csharp
249
+ // Vary by Accept-Language for localized content
250
+ options.AddPolicy("Localized", p => p
251
+ .SetVaryByHeader("Accept-Language")
252
+ .Expire(TimeSpan.FromHours(1)));
253
+
254
+ // Vary by multiple headers
255
+ options.AddPolicy("MultiHeader", p => p
256
+ .SetVaryByHeader("Accept", "Accept-Language", "Accept-Encoding")
257
+ .Expire(TimeSpan.FromMinutes(30)));
258
+ ```
259
+
260
+ ### Vary By Route Values
261
+
262
+ ```csharp
263
+ // Vary by route parameters
264
+ options.AddPolicy("EntityDetails", p => p
265
+ .SetVaryByRouteValue("id")
266
+ .Expire(TimeSpan.FromMinutes(10)));
267
+
268
+ // Minimal API usage
269
+ app.MapGet("/products/{id}", GetProductById)
270
+ .CacheOutput(policy => policy
271
+ .Expire(TimeSpan.FromMinutes(10))
272
+ .SetVaryByRouteValue("id")
273
+ .Tag($"products"));
274
+ ```
275
+
276
+ ## Redis Integration
277
+
278
+ ### Why Use Redis for Output Caching?
279
+
280
+ - **Multi-instance deployments:** Cache is shared across all instances
281
+ - **Persistence:** Cache survives application restarts
282
+ - **Scalability:** Offload memory usage to Redis
283
+ - **Centralized invalidation:** Invalidate across all instances
284
+
285
+ ### Configuration
286
+
287
+ ```csharp
288
+ builder.Services.AddMvp24HoursOutputCacheWithRedis(
289
+ "localhost:6379,abortConnect=false",
290
+ options =>
291
+ {
292
+ options.RedisInstanceName = "myapp:oc:";
293
+ options.DefaultExpirationTimeSpan = TimeSpan.FromMinutes(10);
294
+ options.AddStandardPolicies();
295
+
296
+ // Custom policies
297
+ options.AddPolicy("Products", p => p
298
+ .Expire(TimeSpan.FromMinutes(5))
299
+ .SetTags("products"));
300
+ });
301
+ ```
302
+
303
+ ### Redis Connection Options
304
+
305
+ ```csharp
306
+ builder.Services.AddMvp24HoursOutputCache(options =>
307
+ {
308
+ options.UseDistributedCache = true;
309
+ options.RedisConnectionString =
310
+ "redis-server:6379,password=secret,ssl=True,abortConnect=false";
311
+ options.RedisInstanceName = "prod:oc:";
312
+ });
313
+ ```
314
+
315
+ ## Excluded Paths
316
+
317
+ ```csharp
318
+ builder.Services.AddMvp24HoursOutputCache(options =>
319
+ {
320
+ // Exclude specific paths from caching
321
+ options.ExcludedPaths.Add("/api/health");
322
+ options.ExcludedPaths.Add("/api/admin/*");
323
+ options.ExcludedPaths.Add("/api/auth/*");
324
+ });
325
+ ```
326
+
327
+ ## Configuration Options
328
+
329
+ ### OutputCachingOptions Properties
330
+
331
+ | Property | Type | Default | Description |
332
+ |----------|------|---------|-------------|
333
+ | `Enabled` | bool | `true` | Enable/disable output caching |
334
+ | `DefaultExpirationTimeSpan` | TimeSpan | 5 min | Default cache duration |
335
+ | `MaximumBodySize` | long | 100 MB | Maximum response size to cache |
336
+ | `SizeLimit` | long | 100 MB | Total cache size limit |
337
+ | `UseDistributedCache` | bool | `false` | Enable Redis backend |
338
+ | `RedisConnectionString` | string? | null | Redis connection string |
339
+ | `RedisInstanceName` | string | `"mvp24h-oc:"` | Redis key prefix |
340
+ | `UseCaseSensitivePaths` | bool | `false` | Case-sensitive cache keys |
341
+ | `VaryByQueryStringByDefault` | bool | `true` | Default vary by query |
342
+ | `CacheableMethods` | HashSet | GET, HEAD | HTTP methods to cache |
343
+ | `CacheableStatusCodes` | HashSet | 200 | Status codes to cache |
344
+
345
+ ### OutputCachePolicyOptions Properties
346
+
347
+ | Property | Type | Description |
348
+ |----------|------|-------------|
349
+ | `ExpirationTimeSpan` | TimeSpan? | Cache duration |
350
+ | `NoCache` | bool | Disable caching |
351
+ | `Tags` | HashSet | Invalidation tags |
352
+ | `VaryByHeader` | HashSet | Headers to vary by |
353
+ | `VaryByQueryKeys` | HashSet | Query keys to vary by |
354
+ | `VaryByAllQueryKeys` | bool | Vary by all query keys |
355
+ | `VaryByRouteValue` | HashSet | Route values to vary by |
356
+ | `LockDuringPopulation` | bool | Prevent stampede |
357
+ | `CacheAuthenticatedRequests` | bool | Cache authenticated requests |
358
+
359
+ ## Best Practices
360
+
361
+ ### 1. Use Tags for Invalidation Groups
362
+
363
+ ```csharp
364
+ options.AddPolicy("Products", p => p
365
+ .Expire(TimeSpan.FromMinutes(10))
366
+ .SetTags("products", "catalog"));
367
+
368
+ // Invalidate by tag when data changes
369
+ await _cacheInvalidator.EvictByTagAsync("products");
370
+ ```
371
+
372
+ ### 2. Appropriate Cache Durations
373
+
374
+ ```csharp
375
+ // Frequently changing data - short cache
376
+ options.AddPolicy("RealTimeData", p => p.Expire(TimeSpan.FromSeconds(30)));
377
+
378
+ // Reference data - long cache
379
+ options.AddPolicy("ReferenceData", p => p.Expire(TimeSpan.FromHours(24)));
380
+
381
+ // User-specific data - medium cache with Authorization vary
382
+ options.AddPolicy("UserData", p => p
383
+ .Expire(TimeSpan.FromMinutes(5))
384
+ .SetVaryByHeader("Authorization"));
385
+ ```
386
+
387
+ ### 3. Exclude Sensitive Endpoints
388
+
389
+ ```csharp
390
+ options.ExcludedPaths.Add("/api/auth/*");
391
+ options.ExcludedPaths.Add("/api/payments/*");
392
+ options.ExcludedPaths.Add("/api/admin/*");
393
+ ```
394
+
395
+ ### 4. Use Redis for Production
396
+
397
+ ```csharp
398
+ if (builder.Environment.IsProduction())
399
+ {
400
+ builder.Services.AddMvp24HoursOutputCacheWithRedis(
401
+ configuration["Redis:ConnectionString"]!);
402
+ }
403
+ else
404
+ {
405
+ builder.Services.AddMvp24HoursOutputCache();
406
+ }
407
+ ```
408
+
409
+ ### 5. Combine with HybridCache
410
+
411
+ Output Caching and HybridCache serve different purposes:
412
+
413
+ - **Output Caching:** Cache complete HTTP responses
414
+ - **HybridCache:** Cache application-level data
415
+
416
+ ```csharp
417
+ // Output caching for HTTP responses
418
+ builder.Services.AddMvp24HoursOutputCache(options =>
419
+ {
420
+ options.AddStandardPolicies();
421
+ });
422
+
423
+ // HybridCache for application data
424
+ builder.Services.AddMvpHybridCache();
425
+ ```
426
+
427
+ ## Pipeline Position
428
+
429
+ ```csharp
430
+ var app = builder.Build();
431
+
432
+ // Exception handling first
433
+ app.UseMvp24HoursProblemDetails();
434
+
435
+ // Then CORS
436
+ app.UseCors();
437
+
438
+ // Then authentication/authorization
439
+ app.UseAuthentication();
440
+ app.UseAuthorization();
441
+
442
+ // Output caching after auth (to respect Authorization vary)
443
+ app.UseMvp24HoursOutputCache();
444
+
445
+ // Then routing
446
+ app.MapControllers();
447
+ ```
448
+
449
+ ## See Also
450
+
451
+ - [HybridCache](hybrid-cache.md) - Application-level caching
452
+ - [Rate Limiting](rate-limiting.md) - Request throttling
453
+ - [HTTP Resilience](http-resilience.md) - HTTP client resilience
454
+