Back to School Sale: 40% off all courses

In-depth technical library

Practical .NET and software architecture guides

Go beyond the weekly newsletter with focused, long-form guides built around production decisions, working code, and the trade-offs that matter.

108 published guides

Explore the library

Browse The .NET Weekly archive →
  • EF Core

    Audit Logging With EF Core Interceptors

    A SaveChangesInterceptor gives you one place to capture every insert, update, and delete: the acting user, the old and new values, and the affected columns. This guide builds a complete audit log with EF Core interceptors and covers the traps: sensitive data in the payload, unbounded growth, and bulk updates that bypass the interceptor entirely.

    • clean-architecture
    • dotnet
    • ef-core
    Read the guide →
  • EF Core

    EF Core DbContext: Configuration and Best Practices

    DbContext configuration decides how your app behaves under load: service lifetime, tracking defaults, pooling, retries, and interceptors. This guide covers the settings that matter, the mistakes that cause concurrency bugs, and when context pooling is actually worth it.

    • dotnet
    • ef-core
    • performance
    Read the guide →
  • EF Core

    Repository Pattern in C# With Entity Framework Core

    The repository pattern is one of the most debated patterns in .NET. This guide shows a clean EF Core implementation, explains why generic repositories backfire, and tells you exactly when to skip the pattern entirely.

    • clean-architecture
    • csharp
    • design-patterns
    Read the guide →
  • EF Core

    Unit of Work Pattern With EF Core

    EF Core DbContext already implements the Unit of Work pattern. But sometimes you need an explicit abstraction. Here is when and how to implement IUnitOfWork with EF Core.

    • dotnet
    • ef-core
    • software-architecture
    Read the guide →
  • EF Core

    Cascade Delete in EF Core: Behaviors and Pitfalls

    DeleteBehavior in EF Core controls two different things that people conflate: what EF does to tracked entities in memory, and what the database enforces with ON DELETE. The two can disagree, and when they do you get deletes that work in tests and fail in production. Here is the full map.

    • database
    • dotnet
    • ef-core
    Read the guide →
  • EF Core

    Identity vs Sequence vs HiLo Key Generation in EF Core

    Identity columns are the default, but they only hand you the id after the insert. HiLo assigns ids before SaveChanges, which unlocks setting foreign keys on unsaved object graphs and leaner batch inserts. Here is how all three strategies work and how to pick.

    • database
    • ef-core
    • performance
    Read the guide →
  • EF Core

    Optimistic Concurrency With Postgres xmin in EF Core

    Two users edit the same row, and the last write silently wins. PostgreSQL already versions every row internally through the xmin system column, and EF Core can use it as a concurrency token with zero schema changes. Here is how to map it, handle the conflict, and the caveats you should know before shipping it.

    • concurrency
    • ef-core
    • postgresql
    Read the guide →
  • EF Core

    Computed Columns in EF Core

    Derived values calculated in C# drift out of sync the moment someone updates the database directly. Computed columns push the calculation into the database itself, so the value is always consistent. Here is how to map them in EF Core, and why the stored vs virtual choice decides whether you can index them.

    • database
    • dotnet
    • ef-core
    Read the guide →
  • EF Core

    Custom Model Conventions in EF Core

    Fifty entity configurations all setting the same string length and decimal precision is not configuration, it is copy-paste. EF Core lets you define model-wide conventions once with ConfigureConventions, and write your own convention classes for anything it does not cover.

    • clean-architecture
    • dotnet
    • ef-core
    Read the guide →
  • EF Core

    Modeling Hierarchical Data in EF Core

    Categories with subcategories, org charts, comment threads: hierarchies are everywhere, and the obvious self-referencing entity is easy to write and brutal to query recursively. Here is how to model adjacency lists in EF Core, load whole trees without N+1 queries, and when to reach for recursive CTEs or Postgres ltree instead.

    • database
    • dotnet
    • ef-core
    Read the guide →
  • EF Core

    Composite Primary Keys in EF Core

    Composite primary keys look like a simple HasKey call, but they change how Find works, how relationships are configured, and how your indexes behave. Here is how to configure them correctly and when a surrogate key is the better choice.

    • database
    • dotnet
    • ef-core
    Read the guide →
  • EF Core

    Mapping Enums in EF Core: Strings, Ints, and Native Postgres Enums

    EF Core stores enums as ints by default, which breaks the day someone reorders the enum. Storing them as strings survives refactoring, but it silently changes how ORDER BY and comparisons translate to SQL. Here are all three options, including native PostgreSQL enums, and when each one wins.

    • database
    • dotnet
    • ef-core
    Read the guide →
  • EF Core

    Mapping JSON Columns in EF Core

    Some data does not deserve its own table: settings blobs, address snapshots, flexible metadata. JSON columns give you document flexibility inside a relational row, and with ToJson in EF Core you keep LINQ querying into the JSON. Here is how to map, query, update, and index them.

    • database
    • dotnet
    • ef-core
    Read the guide →
  • EF Core

    Shadow Properties in EF Core Explained

    Shadow properties exist in the EF Core model but not in your entity classes. They are useful for audit fields, foreign keys, and metadata you want in the database but not in your domain model.

    • dotnet
    • ef-core
    Read the guide →
  • EF Core

    Value Conversions in EF Core Explained

    Value conversions translate between a domain type and its database column: enums stored as strings, strongly typed IDs stored as Guids, value objects stored as scalars. Here is how to use HasConversion, when you need a ValueComparer, and where converted properties break LINQ translation.

    • dotnet
    • ef-core
    Read the guide →
  • EF Core

    Complex Types in EF Core 8: What You Need to Know

    Complex types map value objects with no identity into the owner's table. In EF Core 8 they were always required, and EF Core 10 added optional complex properties plus JSON mapping with collection support. Here is how to configure, query, and update them.

    • ddd
    • dotnet
    • ef-core
    Read the guide →
  • EF Core

    How to Use EF Core With Multiple Databases

    In most applications a single database is enough. But when you need to split data across databases - for scaling, multi-tenancy, or module isolation - EF Core supports it cleanly with multiple DbContexts.

    • dotnet
    • ef-core
    Read the guide →
  • EF Core

    EF Core Migration Bundles for CI/CD Deployments

    Calling Database.Migrate at startup means your schema changes run when the app boots, with the app pool racing itself and failures taking production down. Migration bundles package migrations into a self-contained executable that runs as a pipeline step, so a bad migration fails the deploy, not the app.

    • database
    • devops
    • ef-core
    Read the guide →
  • EF Core

    How to Roll Back an EF Core Migration

    Rolling back an EF Core migration is two commands, but only in the right order. Delete the migration file first and EF Core loses the ability to generate the Down SQL, leaving your database and model out of sync. Here is the safe sequence for local, shared, and production databases.

    • database
    • devops
    • ef-core
    Read the guide →
  • EF Core

    Zero-Downtime Database Migrations With EF Core

    Deploying database changes without downtime requires careful planning. The expand-contract pattern, additive-only migrations, and backwards-compatible changes make zero-downtime deployments possible with EF Core.

    • devops
    • dotnet
    • ef-core
    Read the guide →
  • EF Core

    Fixing "Cannot Write DateTime with Kind=Local" With Npgsql

    Npgsql throws "Cannot write DateTime with Kind=Unspecified to PostgreSQL type timestamp with time zone" the first time a non-UTC DateTime reaches the database. The legacy switch makes it go away and your timestamps wrong. Normalizing Kind at the boundary makes both go away.

    • database
    • dotnet
    • ef-core
    Read the guide →
  • EF Core

    EF Core Compiled Models for Faster Startup

    Large DbContexts pay a model-building tax on first use, and it grows with every entity you add. Compiled models move that work to build time and can cut cold start by an order of magnitude. They also come with real restrictions, including a hard conflict with global query filters, that decide who should use them.

    • dotnet
    • ef-core
    • performance
    Read the guide →
  • EF Core

    Fixing PendingModelChangesWarning in EF Core 9

    EF Core 9 throws "The model for context has pending changes" when your model no longer matches the last migration. Sometimes you really did forget a migration. But the sneaky trigger is dynamic values in HasData seed data, where every model build looks like a new change. Here is how to diagnose and fix both.

    • debugging
    • dotnet
    • ef-core
    Read the guide →
  • EF Core

    AsNoTracking vs AsNoTrackingWithIdentityResolution

    AsNoTracking is the standard advice for read-only EF Core queries, but it has a side effect few people notice: shared related entities get duplicated in memory, one copy per parent row. AsNoTrackingWithIdentityResolution fixes that for a small CPU cost. Here is when each one wins.

    • dotnet
    • ef-core
    • performance
    Read the guide →
  • EF Core

    DbContext Pooling in EF Core: When It Helps and When It Bites

    AddDbContextPool can shave allocations off every request by recycling DbContext instances instead of creating them. But a pooled context is a reused object, and any state you stash on it silently leaks into the next request. Here is when pooling pays off and how to avoid its traps.

    • aspnetcore
    • ef-core
    • performance
    Read the guide →
  • EF Core

    Find vs FirstOrDefault in EF Core

    FindAsync and FirstOrDefaultAsync look interchangeable for loading by primary key, but they behave differently in one crucial way: Find checks the change tracker before touching the database. That is either a free cache hit or a stale-data surprise, depending on your code.

    • dotnet
    • ef-core
    • performance
    Read the guide →
  • Vertical Slice Architecture

    Combining Vertical Slices With CQRS in .NET

    CQRS and Vertical Slice Architecture are a natural pair. Commands and queries are already separate - putting each in its own slice makes them independent and easy to optimize.

    • clean-architecture
    • dotnet
    • vertical-slice-architecture
    Read the guide →
  • Vertical Slice Architecture

    Cross-Cutting Concerns in Vertical Slice Architecture

    One criticism of Vertical Slice Architecture is code duplication across slices. Here is how to handle cross-cutting concerns like validation, logging, and caching without breaking feature isolation.

    • dotnet
    • software-architecture
    • vertical-slice-architecture
    Read the guide →
  • Modular Monoliths

    Defining Module Boundaries With Bounded Contexts

    Draw module boundaries wrong and you fight your own architecture on every feature. Bounded contexts give you a systematic way to draw them: map business capabilities, give each module its own language and data, and validate with the change test. Plus the three boundary mistakes that sink most modular monoliths.

    • ddd
    • modular-monolith
    • software-architecture
    Read the guide →
  • Modular Monoliths

    Event-Driven Communication Between Modules in .NET

    The Ordering module publishes an event, and Shipping and Notifications react without the publisher knowing they exist. The catch: an in-process event bus runs every handler synchronously in the caller's scope, so a slow or failing consumer becomes the publisher's problem. Here is the full setup, and the point where the outbox pattern has to take over.

    • distributed-systems
    • dotnet
    • modular-monolith
    Read the guide →
  • Vertical Slice Architecture

    Feature Folders in .NET: Organizing Code by Feature

    Stop organizing code by technical concern (Controllers, Services, Models). Organize by feature instead - so everything related to placing an order lives in one folder. Here is how to implement feature folders in .NET.

    • dotnet
    • software-architecture
    • vertical-slice-architecture
    Read the guide →
  • Modular Monoliths

    How to Build a Modular Monolith in .NET Step by Step

    Build a working Modular Monolith skeleton in .NET: three modules, each with its own schema and DbContext, cross-module calls that go through Contracts projects only, and an in-process event bus. Architecture tests fail the build the moment someone crosses a boundary.

    • dotnet
    • modular-monolith
    • software-architecture
    Read the guide →
  • Modular Monoliths

    Saga Pattern in a Modular Monolith

    Placing an order touches Ordering, Inventory, Payment, and Shipping, and any step can fail after the previous ones already committed. The saga pattern breaks the process into local transactions with compensating actions, coordinated by an orchestrator that fits in one class. Here is how to build one inside a modular monolith, without a distributed transaction in sight.

    • distributed-systems
    • dotnet
    • modular-monolith
    Read the guide →
  • Modular Monoliths

    Schema-Per-Module vs Database-Per-Module: Which Data Isolation Strategy Should You Pick?

    Schema-per-module and database-per-module both enforce module boundaries at the data layer, but they differ sharply on transactions, operations, and your path to microservices. Here is the EF Core setup for both, the five trade-offs that actually matter, and the triggers that tell you when to graduate from schemas to separate databases.

    • dotnet
    • ef-core
    • modular-monolith
    Read the guide →
  • Modular Monoliths

    Strangler Fig Pattern for Modular Monolith Migration

    Big-bang rewrites fail for predictable reasons: they take longer than planned, the legacy system keeps changing underneath them, and the business sees nothing until the end. The Strangler Fig pattern replaces a legacy monolith one bounded context at a time, with feature-flag routing, data sync, and a parallel run before every cutover. The system stays fully functional throughout.

    • dotnet
    • modular-monolith
    • software-architecture
    Read the guide →
  • Vertical Slice Architecture

    Testing Vertical Slices in .NET

    Vertical slices change the shape of your tests. Instead of repository, service, and controller tests held together by mocks, you test one feature at a time: validators in microseconds, handlers in isolation, and the full slice from HTTP to database with WebApplicationFactory and Testcontainers.

    • dotnet
    • testing
    • vertical-slice-architecture
    Read the guide →
  • Vertical Slice Architecture

    Vertical Slice Architecture vs Clean Architecture

    Clean Architecture manages complexity through layer discipline. Vertical Slice Architecture manages it through feature isolation. Teams treat this as a religious war, but it is a fit question: rich shared domain logic points one way, features with wildly different complexity point the other. Here is how the two compare, and the hybrid most real projects land on.

    • clean-architecture
    • dotnet
    • software-architecture
    Read the guide →
  • Vertical Slice Architecture

    Vertical Slice Architecture With Carter in .NET

    Carter turns Minimal API endpoints into self-registering modules: each feature defines its routes, and app.MapCarter() wires them up at startup. Combined with Vertical Slice Architecture, every feature owns its endpoint, handler, and validator in one folder. Here is the full setup, from installation to integration tests.

    • aspnetcore
    • dotnet
    • vertical-slice-architecture
    Read the guide →
  • Vertical Slice Architecture

    When to Choose Vertical Slice Architecture Over Layered Architecture

    Four files across four folders for a query that returns one object: that is the layered tax on every feature. Sometimes the tax buys you real structure, and sometimes it buys you nothing. Here are the concrete signals that tell you when Vertical Slice Architecture is the better fit for your .NET project, and when layers still win.

    • dotnet
    • software-architecture
    • vertical-slice-architecture
    Read the guide →
  • Modular Monoliths

    When to Extract a Module Into a Microservice

    Extract a module too early and you lock unstable boundaries into network contracts. Wait too long and extraction becomes a multi-month rewrite. These are the four concrete drivers that justify extracting a module into a microservice, the readiness checklist to pass first, and the extraction process that keeps a rollback path open.

    • dotnet
    • microservices
    • modular-monolith
    Read the guide →
  • Clean Architecture

    Authentication and Authorization in Clean Architecture

    Authentication is infrastructure, authorization is a business rule, and confusing the two is how ASP.NET Core leaks into your domain. Here is where JWT validation, the ICurrentUserService abstraction, permission checks, and ownership rules each live, and how to keep them enforced beyond HTTP endpoints.

    • clean-architecture
    • dotnet
    • security
    Read the guide →
  • Clean Architecture

    Background Jobs in Clean Architecture

    Where do background jobs fit in Clean Architecture? Treat them as entry points, exactly like controllers. The job schedules and triggers, the application layer does the work. Here is the structure, the scoped-service wiring that trips everyone up, and complete examples with BackgroundService and Quartz.

    • aspnetcore
    • background-jobs
    • clean-architecture
    Read the guide →
  • Clean Architecture

    Clean Architecture Solution Template for .NET

    Setting up a Clean Architecture project from scratch takes time. Here is a complete .NET solution template with the right project structure, references, and configurations.

    • clean-architecture
    • dotnet
    • software-architecture
    Read the guide →
  • Clean Architecture

    Clean Architecture vs Onion Architecture vs Hexagonal Architecture

    Clean Architecture, Onion Architecture, and Hexagonal Architecture all solve the same fundamental problem: decoupling business logic from infrastructure. But they differ in structure, naming, and emphasis. Here is a practical comparison to help you choose.

    • clean-architecture
    • dotnet
    • software-architecture
    Read the guide →
  • Clean Architecture

    Clean Architecture With Minimal APIs in .NET

    Minimal API endpoints and Clean Architecture are a natural fit: the endpoint receives HTTP, dispatches a command, and maps the result back. No business logic, no controllers, no ceremony. Here is how to organize endpoints by feature, validate with endpoint filters, and return consistent Problem Details.

    • aspnetcore
    • clean-architecture
    • dotnet
    Read the guide →
  • Clean Architecture

    Dependency Rule in Clean Architecture Explained

    Source code dependencies must only point inward. That one sentence decides your project references, where your interfaces live, and why the DI container sits at the edge. Here is how the Dependency Rule works, how control can flow outward while dependencies point inward, and how to enforce it with the compiler and architecture tests.

    • clean-architecture
    • dotnet
    • software-architecture
    Read the guide →
  • Clean Architecture

    Domain Events vs Integration Events in .NET

    A domain event is handled in-process, inside the same transaction. An integration event crosses service boundaries through a message broker and needs the outbox pattern to survive a crash. Confusing the two leads to lost events and accidental coupling. Here is where the line sits, with implementation patterns for both sides.

    • clean-architecture
    • ddd
    • distributed-systems
    Read the guide →
  • Clean Architecture

    Exception Handling Strategy in Clean Architecture

    Expected failures are not exceptional, so stop throwing them. A clear strategy gives each layer one job: the domain throws on invariant violations, the application returns typed Results, and a single global handler maps everything else to Problem Details. Here is how the pieces fit together in a .NET Clean Architecture.

    • clean-architecture
    • dotnet
    • software-architecture
    Read the guide →
  • Clean Architecture

    How to Organize Use Cases in Clean Architecture

    A folder structure that works at 5 use cases falls apart at 200. Group by feature, keep one use case per folder, and name with verb-noun domain language, and your Application layer reads like a list of things the system can do. Here are the three layouts you will encounter, and why only one of them scales.

    • clean-architecture
    • dotnet
    • software-architecture
    Read the guide →
  • Clean Architecture

    Logging Strategy in Clean Architecture

    One pipeline behavior can log every use case with timing and failures, so handlers stay clean and the domain never sees an ILogger. Here is a layer-by-layer logging strategy for Clean Architecture: domain events instead of logs in the domain, behaviors in the application, direct logging in infrastructure, and middleware at the edge.

    • clean-architecture
    • dotnet
    • observability
    Read the guide →
  • Clean Architecture

    Mapping Between Layers in Clean Architecture

    Request to command, command to entity, entity to response: a single operation can pass through three mappings, and most of them are ceremony. EF Core projections eliminate the read-side mapping entirely, and simple extension methods handle the rest. Here is when mapping between layers earns its keep, and why you rarely need AutoMapper.

    • clean-architecture
    • design-patterns
    • dotnet
    Read the guide →
  • Clean Architecture

    The Application Layer in Clean Architecture

    The Application layer is where your use cases live: commands, queries, and the handlers that orchestrate your domain objects. A good handler reads like a table of contents (load, act, save). Here is how to structure the layer in .NET and keep business logic from leaking into it.

    • clean-architecture
    • cqrs
    • dotnet
    Read the guide →
  • Clean Architecture

    The Domain Layer in Clean Architecture

    Every business rule in your system should have exactly one home: the Domain layer. That means entities that guard their invariants, value objects instead of raw primitives, and domain events for side effects. Here is what belongs in the Domain layer, what does not, and how to keep it at zero external dependencies.

    • clean-architecture
    • ddd
    • dotnet
    Read the guide →
  • Clean Architecture

    The Infrastructure Layer in Clean Architecture

    Databases, message brokers, email providers, caches: everything that talks to the outside world lives in the Infrastructure layer. It implements the interfaces your inner layers define, and it is the only place EF Core should ever appear. Here is how to structure it in .NET, from repositories and the DbContext to a clean DI registration module.

    • clean-architecture
    • dotnet
    • ef-core
    Read the guide →
  • Clean Architecture

    When to Use Clean Architecture (And When Not To)

    A five-endpoint CRUD API with four projects, domain events, and a CQRS pipeline is over-engineering, not discipline. Clean Architecture pays off on complex domains, long-lived codebases, and multi-team projects. Here is a decision framework for spotting which one you have, and a migration path for when you guess wrong.

    • clean-architecture
    • dotnet
    • software-architecture
    Read the guide →
  • Clean Architecture

    Where Do Transactions Belong in Clean Architecture?

    The use case defines what must succeed or fail together, so the transaction boundary belongs to the application layer. Here are three ways to implement that in .NET, ranked: a single SaveChanges as the implicit boundary, a unit of work abstraction, and a transaction pipeline behavior.

    • clean-architecture
    • dotnet
    • ef-core
    Read the guide →
  • Clean Architecture

    Where Does Caching Belong in Clean Architecture?

    Caching is infrastructure, but the decision to cache is application-level. Get that split wrong and cache concerns leak into your use cases, or worse, into your domain. Here are two clean approaches: a decorator over your repositories and a pipeline behavior driven by the use case itself.

    • caching
    • clean-architecture
    • dotnet
    Read the guide →
  • Testing

    Architecture Fitness Functions in .NET With ArchUnitNET

    An architecture rule nobody enforces is a wish with a code-review lottery attached. A fitness function turns it into a build failure that names the offending type. Here is how to write them with ArchUnitNET, including slice cycle detection, the three ways a fitness function quietly lies to you, and what to do when your rule set outgrows code.

    • architecture
    • clean-architecture
    • dotnet
    Read the guide →
  • Caching

    Content-Addressed Caching in .NET: Cache Keys That Never Go Stale

    Cache invalidation is hard because we name cache entries after locations. Name them after a hash of their inputs instead, and the whole class of stale-read bugs stops being possible: change any input, get a different key, recompute under it. Git, Docker, and NuGet all run on this idea, and it works just as well inside your own application.

    • architecture
    • caching
    • dotnet
    Read the guide →
  • Clean Architecture

    Clean Architecture in .NET: The Complete Guide

    A practical map of Clean Architecture in .NET: dependency direction, layer responsibilities, use-case organization, cross-cutting concerns, and the tradeoffs that tell you when the structure is worth its cost.

    • clean-architecture
    • dotnet
    • software-architecture
    Read the guide →
  • Databases

    Distributed Locking With Postgres Advisory Locks in .NET

    You probably do not need Redis, RedLock, or ZooKeeper for distributed locking. If your instances already share a Postgres database, they share a lock manager too. Session-level advisory locks serialize work across every instance and auto-release the moment a holder dies, which is the exact property TTL-based leases spend fencing tokens trying to approximate.

    • database
    • distributed-systems
    • dotnet
    Read the guide →
  • Messaging

    How I Use NATS JetStream as a Job Queue in .NET

    My first job queue was a Redis list, and it had two ways to silently lose a job: a worker crash after LPOP, and a broker restart. NATS JetStream closed both with a work-queue stream, a durable pull consumer, and one ordering rule: publish the result before you ack the job. Here is the whole design, small enough to read in five minutes.

    • architecture
    • dotnet
    • messaging
    Read the guide →
  • Modular Monoliths

    Modular Monolith Architecture in .NET: The Complete Guide

    A modular monolith keeps one deployment while enforcing business boundaries inside the codebase. This guide connects module design, data isolation, communication, testing, and the evidence that can justify extracting a service later.

    • dotnet
    • modular-monolith
    • software-architecture
    Read the guide →
  • Observability

    OpenTelemetry Collectors: The Agent + Gateway Pattern

    One OpenTelemetry Collector is easy. The interesting design shows up the moment your apps run on more than one machine: a small agent collector on every box, forwarding to one gateway collector that fans out to Tempo, Loki, and Prometheus. Here is the two-tier setup I run in production, including the two config lines that stop the collector from OOM-killing the box it shares with real workloads.

    • devops
    • dotnet
    • observability
    Read the guide →
  • Databases

    Why Postgres Ignores Your Index (Sargability, Taught by a Kata)

    Your query is correct, your tests pass, and the index you carefully created is never touched. The usual culprit is one innocent-looking habit: wrapping the column in a function. Here is what sargability means, how to catch the problem with EXPLAIN, and how I built a coding kata that grades your query plan so the lesson actually sticks.

    • database
    • performance
    • postgresql
    Read the guide →
  • Performance

    Async/Await Performance Pitfalls in .NET

    Async improves throughput only while the work stays nonblocking. Sync-over-async, accidental serialization, unnecessary state machines, and unbounded fan-out can make an asynchronous endpoint slower or deadlock it entirely.

    • csharp
    • dotnet
    • performance
    Read the guide →
  • Domain-Driven Design

    Bounded Context in DDD Explained With Examples

    Bounded Contexts are the most important strategic pattern in Domain-Driven Design. They define explicit boundaries around domain models, giving the same word different meanings in different contexts. Here is a practical guide with .NET examples.

    • ddd
    • dotnet
    • modular-monolith
    Read the guide →
  • AI for .NET

    Building a RAG System in .NET

    Every RAG demo works until you point it at your own documents and it confidently makes things up. The model is rarely the problem. Chunking, embeddings, and retrieval quality decide whether the answer comes from your data or from thin air. Here is a complete RAG pipeline in .NET with Microsoft.Extensions.AI, PostgreSQL with pgvector, hybrid search, re-ranking, and source attribution.

    • ai
    • dotnet
    Read the guide →
  • API Design

    Choosing the Right HTTP Status Codes for Your API

    Nobody argues about 200 and 500. The fights are in the middle: 400 vs 422, 401 vs 403, 404 vs 410, and whether 200-with-an-error-body is ever acceptable (it is not). A decision tree for the ambiguous cases, with the ASP.NET Core mappings to make it stick.

    • api-design
    • aspnetcore
    • rest
    Read the guide →
  • Databases

    Dapper in .NET: A Practical Guide

    Dapper's value proposition is predictability: the SQL you write is the SQL that runs, with object mapping and nothing else. This guide covers the patterns you need in a real application: queries, parameters, multi-mapping, QueryMultiple, transactions, and where Dapper fits next to EF Core.

    • dapper
    • database
    • dotnet
    Read the guide →
  • EF Core

    EF Core vs Dapper: When to Use Each

    EF Core and Dapper are the two most popular .NET data access libraries. EF Core provides a full ORM with change tracking, migrations, and LINQ. Dapper gives you raw SQL performance with minimal abstraction. Here is when to use each one.

    • dotnet
    • ef-core
    • performance
    Read the guide →
  • Microservices

    Microservices in .NET: Getting Started Guide

    A .NET microservice system needs more than separately deployed APIs: each service owns its data, communication survives partial failure, and traces cross every boundary. This guide builds a small end-to-end system and makes the cost visible before you choose it.

    • dotnet
    • microservices
    • software-architecture
    Read the guide →
  • ASP.NET Core

    Minimal APIs in .NET: Complete Guide

    Minimal APIs are a lightweight way to build HTTP APIs in .NET without controllers, startup classes, or conventions. Here is a complete guide covering routing, validation, authentication, and structuring Minimal APIs at scale.

    • aspnetcore
    • dotnet
    Read the guide →
  • Modular Monoliths

    Modular Monolith vs Microservices: How to Choose

    Modular Monoliths give you most of microservices benefits - loose coupling, independent modules, clear boundaries - without the operational complexity. Here is a practical comparison to help you decide which fits your project.

    • dotnet
    • microservices
    • modular-monolith
    Read the guide →
  • Caching

    Multi-Level Caching in .NET With FusionCache

    Rolling your own IMemoryCache plus Redis gets you 80% of a caching stack and silently skips the three hard parts: cross-instance invalidation, cache stampede, and serving stale data when the source is down. FusionCache gives you L1, L2, a backplane, and all three behaviors out of the box.

    • caching
    • fusioncache
    • performance
    Read the guide →
  • Resilience

    Polly v8: Resilience Pipelines Explained

    Polly v8 replaced policies with resilience pipelines: a rewritten core with allocation-free execution, built-in telemetry, and one composition model instead of PolicyWrap. Here is how the new API maps to the old one, how to register pipelines with DI, and why the order you add strategies changes what your pipeline actually does.

    • aspnetcore
    • dotnet
    • polly
    Read the guide →
  • Messaging

    RabbitMQ vs Kafka for .NET Applications

    RabbitMQ deletes messages once consumed; Kafka keeps them and moves a cursor. That single design decision explains almost every difference between them: replay, fan-out, ordering, routing, and scaling. Understand it and the choice for your .NET system mostly makes itself.

    • kafka
    • messaging
    • rabbitmq
    Read the guide →
  • Distributed Systems

    Saga Pattern in .NET: Managing Distributed Transactions

    The Saga pattern manages distributed transactions across multiple services by breaking them into local transactions with compensating actions. Here is how to implement both orchestration and choreography sagas in .NET.

    • distributed-systems
    • dotnet
    • software-architecture
    Read the guide →
  • Vertical Slice Architecture

    The REPR Pattern in ASP.NET Core

    The REPR pattern (Request-Endpoint-Response) replaces bloated controllers with focused, single-purpose endpoints. Here is how to implement it in ASP.NET Core with Minimal APIs.

    • aspnetcore
    • clean-architecture
    • design-patterns
    Read the guide →
  • Testing

    Unit Testing Best Practices in .NET

    Unit tests should be fast, reliable, and maintainable. But poorly written tests become a burden that slows development. Here are the best practices for writing effective unit tests in .NET.

    • csharp
    • dotnet
    • testing
    Read the guide →