Skip to content
kc@kumarChandrachooda.com:~$ cd /blog/category/net && read --section="01 net" 0%
Topic

.NET

348 articles filed under this topic.

Series in .NET
Series · 15 parts

An Attendance Platform in ASP.NET Core

Badge gates, WFH timers and shift allowances - the shape of a seven-project intranet attendance platform, the onion it almost is, and the roadmap for fourteen more parts.

Series · 4 parts

An Attendance Platform — The Frontend Chapters

A 6.23 MB JavaScript bundle loaded on every page, a manifest that minifies CSS but concatenates JS, and two copies of jQuery - the first of four frontend chapters the attendance series skipped.

Series · 9 parts

Archive-on-Delete with ArchiveKit

Hard deletes destroy the audit trail; soft deletes clutter live tables forever. Introducing ArchiveKit, a .NET library that intercepts deletions and stores immutable archive snapshots with TTL policies and cascade archiving.

Series · 8 parts

Contract Testing with Pactify

Unit tests mock what you assume, end-to-end tests tell you too late - consumer-driven contract testing closes the gap, and a small open-source .NET library called Pactify is the clearest way I know to learn how it works. Part 1 of a series.

Series · 8 parts

Convey — The Missing Chapters

The 22-part Convey series read the packages; it never once walked the sample system that ships with them. Opening the missing chapters with the trip an order takes through Orders, Pricing and Deliveries — and what the samples quietly teach that no package README does.

Series · 10 parts

Entity Versioning with VersionKit

Rename a property, change a type, ship the release - and every payload you stored last year stops deserialising. Introducing VersionKit, a .NET library that declares schema history as attributes and migrates old data on read.

Series · 17 parts

FastEndpoints in Depth

Controllers grow sideways and Minimal APIs grow into soup. FastEndpoints bets on a third shape - one class per endpoint - and this series reads its source to see how the bet is implemented. Part 1 of FastEndpoints in Depth.

Series · 12 parts

FastEndpoints — The Missing Chapters

Seventeen parts of reading FastEndpoints and the series never once mentioned mappers - the entity-translation layer half the endpoint base classes exist to serve. The Missing Chapters opens with the biggest gap: where mappers live, how they are found, and why they are secretly singletons. Part 1 of FastEndpoints — The Missing Chapters.

Series · 15 parts

Five Modules, One Database Each

Inflow is a modular monolith whose modules agree on their boundaries and disagree about everything inside them - a four-project onion next to a single feature-sliced assembly. Part 1 of a series reading the money-moving half of the estate.

Series · 18 parts

GroupFlights — Tactics in Three Dialects

A teaching repo that implements one airline-charter domain three ways on purpose - CRUD, CRUD-plus-rich, and Clean Architecture - and persists it three ways to match. Part 1 of a source-reading series.

Series · 22 parts

Microservices with Convey

Every team's fifth microservice ships with the same four hundred lines of bootstrap code as the first four. Opening a deep-dive series on Convey, the open-source .NET toolkit that turned that boilerplate into thirty composable packages.

Series · 10 parts

Multi-Tenancy in .NET with EF Core

Database-per-tenant, schema-per-tenant, or packed into a shared database? Kicking off a series on building a multi-tenant platform where one EF Core codebase supports all three isolation strategies behind a single control plane.

Series · 15 parts

Nine Services and a Message Bus

DShop is one e-commerce shop stamped out as nine microservices over RabbitMQ - this series reads the real source to see how the topology holds together and where it drifts. Part 1 of Nine Services and a Message Bus.

Series · 13 parts

No Coding Whatsoever

A 2018 API gateway promises that routing, auth, validation and messaging need no code at all - this series reads the source that makes the promise true, and the places where it is not.

Series · 14 parts

One Process, Three Modules

DevMentors' ModularMonolith sample packs three conference-system modules, a mini-framework and one deliberately broken contract into eighty-four C# files - opening a series that reads all of it, defects included.

Series · 11 parts

Real-Time Feeds with FeedR

A guided tour of FeedR, DevMentors' open-source .NET microservices sample for real-time data feeds - six services, Redis pub/sub, Apache Pulsar and a gRPC stream, and the two-tier eventing model that makes it worth reading. Part 1 of a source-level deep dive.

Series · 9 parts

Sagas with Chronicle

Split one database into five services and the transaction you deleted does not disappear - it goes feral. On sagas, compensation, process managers, and Chronicle, the small open-source .NET library this series reads line by line.

Series · 8 parts

Service Discovery Without a Service Mesh

Dozens of Azure Functions and Logic Apps need each other's URLs and keys, and there is no Kubernetes, no sidecar, no mesh to hand them out. How a small .NET library turned one Key Vault and a naming convention into a working discovery layer - the consumer side of a registry made of secrets. Part 1 of a new series.

Series · 11 parts

Six Packages and an Empty Test Project

Reading a repository one project at a time hides everything that lives in the edges between them - and in this estate the edges are where the interesting failures are.

Series · 13 parts

The Convey Consumer Tax

Convey sells a microservice in thirty lines, and Pacco builds ten of them - this series reads the whole estate to price what the framework compresses and what every consumer pays for by hand. Part 1 of The Convey Consumer Tax.

Series · 18 parts

The Database Is the Message Bus

Five executables, zero queues - how an attendance platform coordinated a web app, three Azure Functions and a console job through one SQL database, and what that choice bought and cost. Part 1 of the series.

Series · 16 parts

The Framework Before the Framework

DShop.Common is the shared library nine microservices were built on - and the rough draft of a framework its authors later shipped as Convey.

Series · 15 parts

The Framework Underneath

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.

Series · 15 parts

The Order That Choreographs Itself

Nobody in Pacco approves an order - a vehicle reservation does. A tour of DevMentors' parcel-delivery estate, the domain it models, and the fifteen-part series it earns.

Series · 11 parts

The Repo Is the Lesson

Inflow ships an executable request collection - five .rest files, thirty-seven requests. On a fresh clone nine of them return a 2xx, and eight of those nine are in one file. This series reads the repository itself as the artefact.

Series · 15 parts

Trill — Reading the Services

Trill's Stories service is four projects with a dependency-free domain at the bottom. Its Users service is two projects with everything in one assembly - same author, same week, same estate, opposite answers to what a layer is.

Series · 15 parts

Trill — The Microservices Spine

The DevMentors Trill estate is a nine-service microservices sample spread over eleven sibling repositories with no README, no clone script and no bootstrap tooling - and the only artefact that names the whole system is a Visual Studio solution file.

Coming soon · 1 part Preview

Aspire in Production

What .NET Aspire actually does for a real multi-service system - the AppHost model, service defaults, the dashboard, and the road from F5 to deployment.

Coming soon in .NET
Coming soon Preview Nov 2025

The Dashboard You Get for Free

Wire four services into a .NET Aspire AppHost and run it once - traces, logs, health and environment variables for the whole system, before you have written a single line of observability code. Part 1 of a series on Aspire in production.

Standalone articles
.NET 26 Apr 2025

Getting Transactions Right with EF Core

SaveChanges is already a transaction, until it isn't enough. A tour of explicit transactions, TransactionScope, execution strategies and the failure modes that only show up in production.

Everything in .NET View
.NET 09 Jun 2025

The Logger That Discovers Itself

The estate's transaction logging wrote to blob storage through a dedicated logging function - which consumers located through the same Key Vault registry the logger belongs to. Discovery consuming discovery, the transaction-id thread that made it useful, and the bootstrap questions self-reference always raises. Part 6 of Service Discovery Without a Service Mesh.

.NET 08 Jun 2025

Shipping Discovery as a NuGet Package

One static registration method wires the whole discovery subsystem into an Azure Functions host, and one CI pipeline packs it as a private NuGet package. The lifetime choices in those few lines quietly decide the caching semantics of the entire estate - and a duplicate registration teaches how DI forgives. Part 5 of Service Discovery Without a Service Mesh.

.NET 08 Jun 2025

The Class Name Is the Registry Key

Above raw resolution sits a convention layer - an abstract endpoint base class that derives its Key Vault lookup key from its own type name, a template method separating the call from the interpretation, and a generic proxy that routes by name across every endpoint the DI container knows. Part 4 of Service Discovery Without a Service Mesh.

.NET 07 Jun 2025

One HTTP Client, Two Calling Conventions

Azure Functions want their key in an x-functions-key header; Logic App workflows want a SAS signature in the query string. How a discovery record's type field became a calling-convention discriminator, and how one small HTTP service hid that difference from every caller in the estate. Part 3 of Service Discovery Without a Service Mesh.

.NET 06 Jun 2025

Resolving a Service from a Secret

The resolution path of a Key Vault-backed discovery client - three fail-fast environment variables, DefaultAzureCredential with a user-assigned managed identity, a name composed as service-plus-environment, a tolerant JSON parser, and a process-lifetime cache with a bug I shipped and honest trade-offs I chose. Part 2 of Service Discovery Without a Service Mesh.

.NET 06 Jun 2025

Service Discovery Without a Service Mesh

Dozens of Azure Functions and Logic Apps need each other's URLs and keys, and there is no Kubernetes, no sidecar, no mesh to hand them out. How a small .NET library turned one Key Vault and a naming convention into a working discovery layer - the consumer side of a registry made of secrets. Part 1 of a new series.

.NET 17 May 2025

Every Archive Needs an Expiry Date

Retention as a first-class column: how ArchiveKit stamps ExpiresAt at archive time from a TtlDays attribute, hard-deletes expired rows in bounded batches, and runs the whole thing on Lambda with the hosted services switched off. Also, the rows TTL doesn't clean yet. Part 8 of the Archive-on-Delete with ArchiveKit series.

.NET 17 May 2025

Querying the Graveyard

The read side of archive-on-delete: querying archives through promoted typed columns, digging into jsonb payloads for everything else, polling snapshots with a 202 pattern, and an honest accounting of the restore path ArchiveKit doesn't have yet. Part 9 wraps up the Archive-on-Delete with ArchiveKit series.

.NET 16 May 2025

Rebuilding Objects That No Longer Exist

ArchiveKit's snapshot service assembles a full JSON tree of a deleted object graph using nothing but archive rows - the primary data is already gone. Job tickets, a four-state machine, retries with a terminal Failed state, and the single-table assembly limitation I still owe a fix for. Part 7 of the Archive-on-Delete with ArchiveKit series.

.NET 15 May 2025

How to Delete a Family Together

Correlation ids and cascade archiving in ArchiveKit - how one Guid per save turns scattered archive rows into a reconstructable object graph, why cascade happens through the EF change tracker rather than the database, and two honest limits: a naive root heuristic and a CascadeArchive flag the interceptor doesn't read yet. Part 6 of the Archive-on-Delete with ArchiveKit series.

.NET 15 May 2025

One Attribute, a Scanner, and a Registry

How ArchiveKit wires itself up - the [Archivable] attribute's three knobs, an assembly scanner that fails fast at startup instead of quietly at delete time, the static registry behind every lookup, and the AddArchiveKit configuration surface. Plus an honest note about the source generator that doesn't exist yet. Part 5 of the Archive-on-Delete with ArchiveKit series.

.NET 14 May 2025

An Archive Table That Outlives Its Source

The storage design behind ArchiveKit - typed queryable columns and a jsonb payload from a single write, why the archive's EntityId is an index but deliberately not a foreign key, and the reflective model configuration that builds every archive table from one method call. Part 4 of the Archive-on-Delete with ArchiveKit series.

.NET 13 May 2025

Fourteen Rows at a Time: Batching Math and the Deletes That Dodge You

Why ArchiveKit's inline archive limit defaults to exactly 14, how EF Core's MaxBatchSize turns archiving into arithmetic, and an honest inventory of every deletion path the interceptor cannot see - synchronous saves, ExecuteDelete, and raw SQL. Part 3 of the Archive-on-Delete with ArchiveKit series.

.NET 13 May 2025

Teaching SaveChanges to Archive Before It Deletes

The anatomy of ArchiveKit's SaveChangesInterceptor - detecting soft-deleted entities in the change tracker, building archive rows with zero extra database reads, and the one line of state-flip ordering that keeps EF from cascade-deleting the archive you just wrote. Part 2 of the Archive-on-Delete with ArchiveKit series.

.NET 12 May 2025

Delete Is Never Just Delete

Hard deletes destroy the audit trail; soft deletes clutter live tables forever. Introducing ArchiveKit, a .NET library that intercepts deletions and stores immutable archive snapshots with TTL policies and cascade archiving.

.NET 11 May 2025

Draining the Archive Without Losing a Row

Archive tables are meant to empty out - a background worker migrates their rows into the current table while live traffic reads and write-through updates race it. This part walks the EF backfill's insert-then-conditional-delete choreography and the timestamp that keeps it honest. Part 9 of the Entity Versioning with VersionKit series.

.NET 11 May 2025

The Bill for Versioning Everything

Static registries, Activator-created migrators, a Postgres accent, a flag that does nothing, and no test project - the closing part of the VersionKit series itemises every trade-off in the library, says when you should not use it, and sketches what comes next. Part 10 of the Entity Versioning with VersionKit series.

.NET 10 May 2025

One Query Across Every Version

A point lookup that might hit any of three tables, a list query that should span them all, and writes that must keep a registry honest - this part walks VersionKit's version-aware reader and writer, and the generated UNION view that makes every schema era queryable as if it were current. Part 8 of the Entity Versioning with VersionKit series.

.NET 09 May 2025

Give Old Rows Their Own Table

JSON payloads can migrate lazily because the reader controls the shape - relational rows cannot, because the table is the shape. VersionKit's EF Core answer is table-per-version - archive Orders as Orders_v2 on a schema bump, track every row's home in a registry, and let old rows stay old until something moves them. Part 7 of the Entity Versioning with VersionKit series.

.NET 09 May 2025

Paying Down the Migration Debt

Lazy migration makes deploys instant but taxes every read of old data. VersionKit's backfill service rewrites stale payloads in scheduled batches until the store converges on the current version - in a host, or from a serverless function. Part 6 of the Entity Versioning with VersionKit series.

.NET 08 May 2025

When Attributes Aren't Enough

Splitting a name field, converting a string to a bool, deriving a flag from a total - some migrations are code, not metadata. This part covers VersionKit's three escape hatches and the sharp edges each one carries. Part 5 of the Entity Versioning with VersionKit series.

.NET 07 May 2025

Nobody Writes an Up() Method

At startup VersionKit reflects over your model assembly and compiles property attributes into an executable pipeline - one migration step per version pair, five operation types, all of them deliberately idempotent. Part 3 of the Entity Versioning with VersionKit series.

.NET 07 May 2025

The Watermark and the Walk

Every stored payload carries a __version stamp; every read walks it up one step at a time. This part dissects VersionKit's lazy migration pipeline - the MigrationRunner API, the JsonElement traps System.Text.Json sets for dictionary code, and reading history on purpose. Part 4 of the Entity Versioning with VersionKit series.

.NET 06 May 2025

Five Ways a Property Can Change

Rename, move, add, remove, type change - VersionKit's attribute surface covers five kinds of schema evolution. This part walks the whole declarative API, the merge rules behind stacked attributes, and what the attributes deliberately refuse to express. Part 2 of the Entity Versioning with VersionKit series.

.NET 05 May 2025

Multi-Tenancy Retrospective: What I'd Do Differently

Nine parts of architecture posts lie by omission unless the tenth is the ledger. What earned its keep — isolation as data, MaxTenants = 1, the schema-keyed model cache — and the honest list of shortcuts: plaintext connection strings, cache windows, reflection, and a fan-out loop that still says TODO.