← .NET / C#
Work & Career / .NET / C#Exploring

A playground project for practicing tools/libraries

A small project purely for practicing tools and patterns — some I already know but want to reinforce fresh, some I've never touched — no pressure for any of it to be production-correct.

playgroundlearning-methodology

Why this exists

Not everything here is brand new — some of these I already know and want to practice again from scratch, cleanly, without the baggage of an existing codebase. Others I haven't touched at all. Both belong here: the goal is reps and a first (or renewed) working impression, not correctness or production-readiness.

First 10, roughly easy to hard

  1. FluentValidation — re-implement validation patterns fresh, including cross-field rules and conditional validation I haven't tried before, not just what I already know.
  2. API Versioning — set it up from a blank project, try all three strategies (URL, header, query) side by side instead of just the one I've already used.
  3. Redis Caching — basic cache-aside pattern: check cache, miss, fetch, store with expiry. Simple on purpose, foundation for the harder Redis stuff later (locks, pub/sub).
  4. Calling a third-party API (mock payment gateway) — build a fake external API that sometimes fails/times out, then call it properly: HttpClient, DTOs, error handling, timeouts. Closest thing here to real payment-integration practice without touching a real gateway.
  5. Polly — wrap the flaky third-party call above in retry-with- backoff and a circuit breaker, and actually watch it recover (or correctly give up) instead of trusting the docs' description.
  6. MediatR / CQRS — restructure one feature as controller → mediator → handler, to actually feel the decoupling instead of just reading why it's supposed to help.
  7. Idempotency Keys — simulate the mock payment webhook firing twice, make sure the second call is a no-op instead of double- processing. Natural pairing with #4 and #5.
  8. Concurrency / Distributed Locks — simulate two requests racing for one scarce resource (last item in stock, last seat, whatever), with no protection first to watch it break, then fix it with locking.
  9. Testcontainers + OpenTelemetry — integration tests against a real disposable Postgres/Redis instead of mocks, and trace a request across multiple pieces to see where time actually goes.
  10. Outbox Pattern — guarantee a DB write and a published event either both happen or neither does. Build the naive "write then publish" version first, kill the process mid-write on purpose, then build the outbox version and see the actual difference.

What ties these together

Four, five, and seven form a natural mini-arc — third-party call, made resilient, made idempotent — which is basically what a real payment integration needs. The rest build up toward correctness under concurrency and reliability guarantees, ending on the pattern that ties a DB write to a side effect.