Skip to content
kc@kumarChandrachooda.com:~$ cd /blog/series/the-framework-underneath && read --section="top" 0%
Series

The Framework Underneath

In reading order.

  • 15 parts
  • ≈ 104 min total
  • 15 published
Part 1 17 Jan 2026 7 min read

Five Modules That Cannot See Each Other

Every modular monolith claims its modules are decoupled. Inflow proves it the only way that counts - by having no project reference between any two of them - and then has to build a whole mini-framework to make that survivable. Part 1 of a source-read through the shared layer.

Part 2 18 Jan 2026 7 min read

The Bootstrapper Is Seventy-Six Lines

Inflow's host knows nothing about its five modules - it finds them by scanning DLL filenames and reflecting for an interface. Reading the loader shows why the whole estate is that small, and where a missing settings file silently deletes a module.

Part 3 19 Jan 2026 6 min read

A Namespace Segment Is a Routing Key

One method in Inflow returns the third segment of a type's namespace, lower-cased. Four subsystems route on that string, and nothing anywhere validates it - a namespace rename is a silent behavioural change across the estate.

Part 4 19 Jan 2026 7 min read

Your Type Name Is the Wire Contract

Inflow has no subscribe call and no topic string. A module receives an event by declaring a class with the same simple name, and a single attribute decides whether the delivery is allowed - with a cache that changes the decision, not just its speed.

Part 5 20 Jan 2026 7 min read

Local Contracts, Verified at Boot

Inflow lets each module own a private copy of every event it consumes, then type-checks those copies against the producer at application start. It is consumer-driven contract testing with no broker, no schema registry and about 280 lines - and the check is weaker than the ceremony suggests.

Part 6 21 Jan 2026 6 min read

Four of Eighteen Copies Are Checked

Inflow's boot-time contract verifier is excellent and almost unused. A census of every consumer-side type copy in the estate shows four protected and fourteen not - and the two failure modes are a startup crash and a silently null property.

Part 7 21 Jan 2026 7 min read

The Round Trip That Copies Every Message

Inflow isolates modules by serialising every message to JSON bytes and deserialising it into the receiver's own type - once per receiver. It is the Message Translator done well, and the byte array in the signature tells you exactly which transport it was built for.

Part 8 22 Jan 2026 7 min read

The Bus That Never Leaves the Process

Inflow's message broker is eighty-eight lines with a three-way branch, backed by an unbounded channel and a single background reader. Reading it shows where the delivery guarantee actually is - and that on shutdown, whatever is still queued is discarded without a log line.

Part 9 23 Jan 2026 7 min read

Nine Lines Stop a Stack Overflow

Inflow registers every handler by assembly scan and then wraps them in decorators. Those two techniques are incompatible unless something tells the scanner to skip the decorators - and in this codebase that something is a marker attribute with no tests and no comment explaining what it prevents.

Part 10 23 Jan 2026 7 min read

One Assignment Freezes Every Trace

Inflow carries request identity across its async message boundary in a static AsyncLocal. The line that populates it uses null-coalescing assignment inside a long-lived loop, so every message after the first runs under the first one's correlation id, trace id and user.

Part 11 24 Jan 2026 6 min read

The Outbox That Commits Somewhere Else

Inflow ships a complete transactional outbox - table, poller, cleanup jobs, type registry - and one CreateScope() call means the outbox row commits on a different DbContext from the state change it is supposed to be atomic with.

Part 12 25 Jan 2026 7 min read

An Inbox That Is Really a Ledger

Inflow's inbox writes a row only after the handler succeeds, which makes its own duplicate-check predicate dead code and its name wrong. It is a good Idempotent Receiver with a one-hour memory, a decorator that resolves from the wrong provider, and an orphaned brace pair.

Part 13 25 Jan 2026 8 min read

Two Flags, Four Systems, One That Stalls

Two booleans govern Inflow's messaging spine. Taking their product gives four behaviours - one shipped and working, two working differently, and one that throws a NullReferenceException every second forever because the component that would prevent it only exists in another cell.

Part 14 26 Jan 2026 6 min read

The Container You Build to Read a Setting

Inflow reads every configuration section by building and disposing an entire service provider - twenty-two of them during startup. Two of those calls do not read anything; they mutate a registry, and they only work because of how three singletons were registered.

Part 15 27 Jan 2026 9 min read

Boot Loudly, Fail Quietly

One sentence describes every failure convention in Inflow's shared framework - startup misconfiguration throws, runtime message failure is logged and dropped. The retrospective on fourteen parts of source-reading, including what to steal, what to avoid, and where this design should not go.

Which CV would you like?

Pick the one closest to the role. Each is two pages and carries the same facts.

Applied AI

Agentic AI & Cloud Engineer · multi-agent systems, RAG and MCP on AWS

Cloud & .NET

C#, .NET 10 and ASP.NET Core microservices on AWS and Azure · Terraform & AWS CDK

Data Engineering

AWS lakehouse · Kinesis, Glue (PySpark), Apache Iceberg, Lake Formation

Everything

All three domains, with the standout project from each