Skip to main content

Command Palette

Search for a command to run...

Introducing PowerCSharp: An Ecosystem Built on 20 Years of C# Architecture

Not another extension method library. A layered, modular .NET ecosystem designed around one principle: your application should never be hostage to its dependencies.

Updated
6 min read
Introducing PowerCSharp: An Ecosystem Built on 20 Years of C# Architecture

After spending over two decades writing C# code — from .NET Framework 1.1 all the way to .NET 8 — I’ve accumulated quite a collection of pet peeves.

Why This Blog Exists

I have been writing C# professionally for over 20 years. Enterprise systems. High-throughput APIs. Financial platforms. Healthcare backends. The kind of codebases where a wrong architectural decision in year one costs six months of refactoring in year three.

Over those two decades, I kept solving the same set of problems. Not the same business problems — different domains, different clients, different team sizes. But the same engineering problems:

  • An extension method library that became a grab bag nobody trusted

  • A caching abstraction so tightly coupled to Redis that the test suite required a Docker container

  • A middleware setup copy-pasted across twelve services with zero consistency

  • A feature toggle system that only worked if you knew which environment variable to set

I built PowerCSharp because I was tired of solving these problems in isolation, project by project. This blog documents the architectural decisions behind the ecosystem — not as marketing, but as engineering records.

Every post on this blog is about a decision: what the problem was, what I considered, what I rejected, and what the solution cost me. If you are a Senior Developer, an Architect, or an Engineering lead making technology decisions for .NET projects, this blog is written for you.

What PowerCSharp Is

PowerCSharp is a modular .NET ecosystem published as a set of NuGet packages. It is organized in three layers:

╔══════════════════════════════════════════════════════════════════╗
║  LAYER 3 — PLUGGABLE FEATURES   (independently versioned)       ║
║                                                                  ║
║  ┌────────────────────────────┐  ┌───────────────────────────┐  ║
║  │ Feature.Cache.BitFaster    │  │ Feature.Cache.Disk        │  ║
║  │ (isolates BitFaster.Cache) │  │ (zero third-party deps)   │  ║
║  └──────────────┬─────────────┘  └────────────┬──────────────┘  ║
║                 │                             │                  ║
║  ┌──────────────▼─────────────────────────────▼──────────────┐  ║
║  │ Feature.Cache                 Feature.Cache.Abstractions  │  ║
║  │ (module + options wiring)     (ICacheService, netstandard) │  ║
║  └──────────────────────────────┬────────────────────────────┘  ║
╠══════════════════════════════════╪═══════════════════════════════╣
║  LAYER 2 — FEATURES FRAMEWORK   │                               ║
║                                  ▼                               ║
║  ┌───────────────────────────────────────────────────────────┐  ║
║  │ PowerCSharp.BuiltInFeatures                               │  ║
║  │ (CORS and bundled ASP.NET Core capabilities)              │  ║
║  └──────────────────────────────┬────────────────────────────┘  ║
║  ┌───────────────────────────────▼────────────────────────────┐  ║
║  │ PowerCSharp.Features                                       │  ║
║  │ (engine: discovery, flag resolution, DI, registry, diags)  │  ║
║  └──────────────────────────────┬────────────────────────────┘  ║
║  ┌───────────────────────────────▼────────────────────────────┐  ║
║  │ PowerCSharp.Features.Abstractions                          │  ║
║  │ (IFeatureModule, IFeatureFlagProvider — zero NuGet deps)   │  ║
║  └──────────────────────────────┬────────────────────────────┘  ║
╠══════════════════════════════════╪═══════════════════════════════╣
║  LAYER 1 — CORE LIBRARY         │                               ║
║                                  ▼                               ║
║  ┌───────────────────────────────────────────────────────────┐  ║
║  │ PowerCSharp.Extensions.AspNetCore                         │  ║
║  │ (HTTP utilities, URI manipulation, request cloning)        │  ║
║  └──────────────────────────────┬────────────────────────────┘  ║
║  ┌───────────────────────────────▼────────────────────────────┐  ║
║  │ PowerCSharp.Extensions   PowerCSharp.Utilities             │  ║
║  │ PowerCSharp.Helpers       PowerCSharp.Compatibility        │  ║
║  │ (100+ extensions)         (.NET Framework 4.6.2+ bridge)   │  ║
║  └──────────────────────────────┬────────────────────────────┘  ║
║  ┌───────────────────────────────▼────────────────────────────┐  ║
║  │ PowerCSharp.Core                                           │  ║
║  │ (contracts, interfaces — zero third-party dependencies)    │  ║
║  └───────────────────────────────────────────────────────────┘  ║
╚══════════════════════════════════════════════════════════════════╝

Dependency direction: upward only. Higher layers depend on lower layers.
Lower layers never depend on higher layers.

Thirteen packages. Three layers. One dependency direction rule.

The Three Design Principles

Every architectural decision in PowerCSharp traces back to three principles. These are not aspirations — they are constraints I enforced during design.

Principle 1: Abstractions have zero external dependencies.

Every package named *.Abstractions references only the .NET platform. No NuGet packages. No transitive chains. This matters because abstractions are what your application code depends on. If an abstraction pulls Newtonsoft.Json 13.0.1, you now own that dependency forever — even if you migrate to System.Text.Json. Abstractions must be dependency-free so that any implementor, any consumer, any version of .NET can reference them.

Principle 2: Dependency direction is law.

Core packages do not know that Features packages exist. The Extensions layer does not reference the Features layer. Lower layers are unaware of higher layers. This is enforced at the project reference level, not by convention. If a dependency goes the wrong direction, the build fails.

This rule exists because reverse dependencies create coupling that breaks isolation. The moment PowerCSharp.Core references PowerCSharp.Features, you can no longer evolve or replace the features layer without touching core.

Principle 3: Every missing feature has a safe-off floor.

In the pluggable features layer, a disabled feature never causes a null reference exception in code that depends on it. A NoOpCacheService is registered when cache is off. The dependency is always satisfiable. Your application always compiles and runs — the behavior simply degrades gracefully.

This principle extends to library adoption: you can reference PowerCSharp.Feature.Cache.Abstractions without referencing any provider. Your code compiles. At runtime, you get the NoOp. You can swap in a real provider with a configuration change.

What This Blog Will Cover

This is not a documentation site. The documentation lives in the GitHub repository. This blog covers the decisions behind the code.

The series is structured to match the three layers:

Layer 1 — Core Library:

  • How 100+ extension methods were organized without becoming a grab bag

  • Dynamic LINQ in production: runtime expression parsing, security model, edge cases

  • CWE-73: why path security belongs in the extensions layer, not the application

Layer 2 — Features Framework:

  • Why a feature module engine is architecturally different from a feature flag library

  • The composite flag resolver: N providers, defined precedence, no ambiguity

  • The safe-off NoOp pattern: how disabled features register instead of throwing

Layer 3 — Cache Feature Family:

  • The ICacheService abstraction: why not IMemoryCache, why CacheResult<T>

  • BitFaster.Caching as a provider: isolation model, stampede protection, lock-free reads

  • Building a production disk cache: atomic writes, cross-process locks, LRU eviction

Each post follows the same discipline: problem, alternatives considered, decision made, implementation, tradeoffs, production considerations.

If you are building a .NET library, an enterprise service, or evaluating PowerCSharp for your team — start here.

The first post in the series is next.


Further reading on Medium:

PowerCSharp Technical Blog

Part 2 of 2

PowerCSharp is a comprehensive library of extension methods, utilities, and helper classes designed to enhance your C# development experience. Built by a senior C# architect with 20+ years of experience, this library provides practical, well-tested solutions for common programming challenges.

Start from the beginning

One Rule, 10+ Packages: How I Designed the PowerCSharp Package Topology

Modular NuGet packages are not free. Here is exactly what they cost, why I paid it, and the single rule that keeps 13 packages coherent.

More from this blog

P

PowerCSharp

2 posts

PowerCSharp is a comprehensive library of extension methods, utilities, and helper classes designed to enhance your C# development experience.

Built by a senior C# architect with 20+ years of experience, this library provides practical, well-tested solutions for common programming challenges.