# Milan Jovanović: full content catalog > Every published article and newsletter issue on milanjovanovic.tech, grouped by > topic, with canonical URLs and one-sentence summaries. Articles are evergreen, > maintained guides (the date shown is the last update). Newsletter issues are > weekly deep dives from The .NET Weekly. The curated entry point with site-level > context is https://milanjovanovic.tech/llms.txt. ## AI for .NET - [Building a RAG System in .NET](https://milanjovanovic.tech/blog/rag-system-dotnet) (updated 2026-07-14): Every RAG demo works until you point it at your own documents and it confidently makes things up. ## API Design - [Choosing the Right HTTP Status Codes for Your API](https://milanjovanovic.tech/blog/rest-api-http-status-codes) (updated 2026-07-14): 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… ## ASP.NET Core - [Minimal APIs in .NET: Complete Guide](https://milanjovanovic.tech/blog/minimal-apis-dotnet) (updated 2026-07-14): Minimal APIs are a lightweight way to build HTTP APIs in .NET without controllers, startup classes, or conventions. ## C# - [C# Records: When and How to Use Them](https://milanjovanovic.tech/blog/csharp-records-when-how) (updated 2026-07-14): Records in C# provide value equality, immutability, and concise syntax. Use them for DTOs, commands, queries, and events, and keep classes for entities and… ## Caching - [Content-Addressed Caching in .NET: Cache Keys That Never Go Stale](https://milanjovanovic.tech/blog/content-addressed-cache-dotnet) (2026-07-25): 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… - [Multi-Level Caching in .NET With FusionCache](https://milanjovanovic.tech/blog/fusioncache-multi-level-caching-dotnet) (updated 2026-07-14): Rolling your own IMemoryCache plus Redis gets you 80% of a caching stack but skips three hard problems: cross-instance invalidation, cache stampede, and… ## Clean Architecture - [When to Use Clean Architecture (And When Not To)](https://milanjovanovic.tech/blog/when-to-use-clean-architecture) (2026-08-11): A five-endpoint CRUD API with four projects, domain events, and a CQRS pipeline is over-engineering. - [Where Do Transactions Belong in Clean Architecture?](https://milanjovanovic.tech/blog/transactions-clean-architecture) (2026-08-11): The use case defines what must succeed or fail together, so the transaction boundary belongs to the application layer. - [How to Organize Use Cases in Clean Architecture](https://milanjovanovic.tech/blog/organize-use-cases-clean-architecture) (2026-08-11): 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… - [MediatR Pipeline Behaviors: A Practical Guide to Cross-Cutting Concerns](https://milanjovanovic.tech/blog/mediatr-pipeline-behaviors) (2026-08-11): MediatR pipeline behaviors let you handle logging, validation, caching, and transactions without touching your handlers. - [Mapping Between Layers in Clean Architecture](https://milanjovanovic.tech/blog/mapping-between-layers-clean-architecture) (2026-08-11): Request to command, command to entity, entity to response: a single operation can pass through three mappings, and most of them are ceremony. - [Logging Strategy in Clean Architecture](https://milanjovanovic.tech/blog/logging-strategy-clean-architecture) (2026-08-11): One pipeline behavior can log every use case with timing and failures, so handlers stay clean and the domain never sees an ILogger. - [The Infrastructure Layer in Clean Architecture](https://milanjovanovic.tech/blog/infrastructure-layer-clean-architecture) (2026-08-11): Databases, message brokers, email providers, caches: everything that talks to the outside world belongs in the Infrastructure layer. - [Exception Handling Strategy in Clean Architecture](https://milanjovanovic.tech/blog/exception-handling-clean-architecture) (2026-08-11): Expected failures are not exceptional, so stop throwing them. A clear strategy gives each layer one job: the domain throws on invariant violations, the… - [The Domain Layer in Clean Architecture](https://milanjovanovic.tech/blog/domain-layer-clean-architecture) (2026-08-11): Every business rule in your system belongs in the Domain layer and nowhere else. That means entities that guard their invariants, value objects instead of raw… - [Domain Events vs Integration Events in .NET](https://milanjovanovic.tech/blog/domain-events-vs-integration-events) (2026-08-11): A domain event is handled in-process, inside the same transaction. An integration event crosses service boundaries through a message broker and needs the… - [Dependency Rule in Clean Architecture Explained](https://milanjovanovic.tech/blog/dependency-rule-clean-architecture) (2026-08-11): Source code dependencies must only point inward. That rule determines your project references, where you define interfaces, and why the DI container is… - [Clean Architecture vs Onion Architecture vs Hexagonal Architecture](https://milanjovanovic.tech/blog/clean-architecture-vs-onion-vs-hexagonal) (2026-08-11): Clean Architecture, Onion Architecture, and Hexagonal Architecture all solve the same problem: decoupling business logic from infrastructure. - [Clean Architecture Solution Template for .NET](https://milanjovanovic.tech/blog/clean-architecture-solution-template-dotnet) (2026-08-11): Setting up a Clean Architecture project from scratch takes time. Here is a .NET solution template with the project structure, references, and configuration… - [Clean Architecture With Minimal APIs in .NET](https://milanjovanovic.tech/blog/clean-architecture-minimal-apis) (2026-08-11): Minimal API endpoints and Clean Architecture are a natural fit: the endpoint receives HTTP, dispatches a command, and maps the result back, with no business… - [Where Does Caching Belong in Clean Architecture?](https://milanjovanovic.tech/blog/caching-clean-architecture) (2026-08-11): 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… - [Background Jobs in Clean Architecture](https://milanjovanovic.tech/blog/background-jobs-clean-architecture) (2026-08-11): Background jobs in Clean Architecture are entry points, exactly like controllers. The job only schedules and triggers; the application layer does the work. - [Authentication and Authorization in Clean Architecture](https://milanjovanovic.tech/blog/authentication-authorization-clean-architecture) (2026-08-11): Authentication is infrastructure and authorization is a business rule. Mixing the two up pulls ASP.NET Core into your domain. - [The Application Layer in Clean Architecture](https://milanjovanovic.tech/blog/application-layer-clean-architecture) (2026-08-11): The Application layer is where your use cases live: commands, queries, and the handlers that orchestrate your domain objects. - [Clean Architecture in .NET: The Complete Guide](https://milanjovanovic.tech/blog/clean-architecture-dotnet) (updated 2026-07-14): A practical map of Clean Architecture in .NET: dependency direction, layer responsibilities, use-case organization, cross-cutting concerns, and the tradeoffs… - [Clean Architecture Anti-Patterns and Common Mistakes](https://milanjovanovic.tech/blog/clean-architecture-anti-patterns) (updated 2026-07-14): Clean Architecture is easy to get wrong. Here are the most common anti-patterns and mistakes I see in .NET projects, and how to fix them. ## Databases - [Why Postgres Ignores Your Index (Sargability, Taught by a Kata)](https://milanjovanovic.tech/blog/sql-index-not-used-sargability) (2026-07-10): Your query is correct and your tests pass, but the index you created is never touched. The usual culprit is wrapping the column in a function. - [Distributed Locking With Postgres Advisory Locks in .NET](https://milanjovanovic.tech/blog/postgres-advisory-locks-dotnet) (2026-07-10): 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… - [Dapper in .NET: A Practical Guide](https://milanjovanovic.tech/blog/dapper-dotnet-guide) (updated 2026-07-14): Dapper runs exactly the SQL you write and maps the results to objects, with nothing else in between. ## DevOps - [Docker for .NET Developers: A Complete Guide](https://milanjovanovic.tech/blog/docker-dotnet-developers) (updated 2026-07-14): Docker simplifies deployment by packaging your .NET application with its dependencies into a container. ## Distributed Systems - [Saga Pattern in .NET: Managing Distributed Transactions](https://milanjovanovic.tech/blog/saga-pattern-dotnet) (updated 2026-07-14): The Saga pattern manages distributed transactions across multiple services by breaking them into local transactions with compensating actions. ## Domain-Driven Design - [How to Model Value Objects With EF Core](https://milanjovanovic.tech/blog/value-objects-ef-core) (2026-09-22): Value objects have no identity; they are defined by their properties. EF Core gives you three ways to persist them: owned types, complex types, and value… - [Ubiquitous Language in Domain-Driven Design](https://milanjovanovic.tech/blog/ubiquitous-language-ddd) (2026-09-22): Ubiquitous language puts the same business terms in conversations, code, and tests. Use precise operation names, respect differences between bounded contexts… - [Transaction Script vs Domain Model Pattern](https://milanjovanovic.tech/blog/transaction-script-vs-domain-model) (2026-09-22): A transaction script puts a use case in one procedure; a domain model puts business rules inside domain objects. - [Strongly Typed IDs in C# to Prevent Primitive Obsession](https://milanjovanovic.tech/blog/strongly-typed-ids-csharp) (2026-09-22): Passing Guid parameters around is error-prone. Strongly typed IDs wrap primitives in domain-specific types so you cannot accidentally pass an OrderId where a… - [Strategic DDD vs Tactical DDD Explained](https://milanjovanovic.tech/blog/strategic-vs-tactical-ddd) (2026-09-22): Strategic DDD tells you where to draw boundaries. Tactical DDD tells you how to model within those boundaries. - [Specification Pattern in C# With EF Core](https://milanjovanovic.tech/blog/specification-pattern-csharp) (2026-09-22): The Specification pattern encapsulates query logic into reusable objects. Combined with EF Core, it eliminates query duplication and keeps your repositories… - [Rich Domain Model vs Anemic Domain Model in C#](https://milanjovanovic.tech/blog/rich-vs-anemic-domain-model) (2026-09-22): An anemic domain model separates data from behavior. A rich domain model keeps them together. - [Process Manager vs Saga: What's the Difference?](https://milanjovanovic.tech/blog/process-manager-vs-saga-pattern) (2026-09-22): A saga coordinates local transactions and recovery across services. A process manager tracks workflow state and decides the next step. - [Persistence Ignorance With EF Core: How Close Can You Get?](https://milanjovanovic.tech/blog/persistence-ignorance-ef-core-ddd) (2026-09-22): EF Core can persist rich domain models without public setters or mapping attributes. Private constructors, backing fields, and external configuration keep… - [Factory Pattern in Domain-Driven Design With C#](https://milanjovanovic.tech/blog/factory-pattern-domain-driven-design) (2026-09-22): Factories encapsulate complex object creation logic in DDD. Here is when and how to use factories for creating aggregates, entities, and value objects in C#. - [EventStorming for .NET Teams: A Practical Guide](https://milanjovanovic.tech/blog/eventstorming-guide) (2026-09-22): EventStorming brings domain experts and developers together to explore a business process through events. - [Event Sourcing in .NET: Aggregates, Event Stores, and Projections](https://milanjovanovic.tech/blog/event-sourcing-dotnet-beginners-guide) (2026-09-22): Build an event-sourced aggregate, an append-only event store, and a replayable read model in C#. - [Entity vs Value Object in Domain-Driven Design](https://milanjovanovic.tech/blog/entity-vs-value-object-ddd) (2026-09-22): Entities have identity. Value Objects have equality by attributes. Here is a practical comparison of when to use each, with C# examples. - [Encapsulating Collections in Domain Entities](https://milanjovanovic.tech/blog/encapsulating-collections-domain-entities) (2026-09-22): Exposing mutable collections on domain entities breaks encapsulation and lets callers bypass business rules. - [Domain Services in DDD: When and How to Use Them](https://milanjovanovic.tech/blog/domain-services-ddd) (2026-09-22): Domain Services handle business logic that does not naturally belong to a single entity or value object. - [Business Rules Pattern in C#: Guard Clauses, Rule Objects, and Result-Based Validation](https://milanjovanovic.tech/blog/domain-invariants-business-rules) (2026-09-22): There are five practical ways to implement business rules in C#: guard clauses, rule objects, the result pattern, value objects, and factory methods. - [Domain-Driven Design in .NET: Getting Started](https://milanjovanovic.tech/blog/domain-driven-design-dotnet-getting-started) (2026-09-22): Domain-Driven Design connects business language and boundaries to the rules in your code. Start with bounded contexts, then implement entities, value objects… - [Context Mapping in DDD: Relationships Between Bounded Contexts](https://milanjovanovic.tech/blog/context-mapping-ddd) (2026-09-22): Conformist, partnership, customer-supplier: each context mapping pattern describes a power relationship between teams and predicts which team absorbs breaking… - [Application Services vs Domain Services in DDD](https://milanjovanovic.tech/blog/application-services-vs-domain-services-ddd) (2026-09-22): Application services coordinate use cases. Domain services hold business rules that do not fit one entity or value object. - [Anti-Corruption Layer in Domain-Driven Design](https://milanjovanovic.tech/blog/anti-corruption-layer-ddd) (2026-09-22): An Anti-Corruption Layer keeps an external system's concepts out of your domain model. It translates between your domain language and the models of legacy… - [The Always-Valid Domain Model](https://milanjovanovic.tech/blog/always-valid-domain-model) (2026-09-22): An always-valid domain model enforces business invariants at construction and on every state change. - [Aggregate Root in DDD: Rules and Implementation](https://milanjovanovic.tech/blog/aggregate-root-ddd) (2026-09-22): The Aggregate Root is the single entry point for changes to an aggregate in Domain-Driven Design. - [Aggregate Design in DDD - Rules, Boundaries, and Consistency](https://milanjovanovic.tech/blog/aggregate-design-ddd) (2026-09-22): Aggregates define consistency boundaries in Domain-Driven Design and enforce the invariants inside them. - [Bounded Context in DDD Explained With Examples](https://milanjovanovic.tech/blog/bounded-context-ddd-explained) (updated 2026-09-04): Bounded contexts let Ordering and Fulfillment use different models of the same concepts. Define those boundaries in .NET, translate integration contracts, and… ## EF Core - [Temporal Tables in EF Core for Data Auditing](https://milanjovanovic.tech/blog/temporal-tables-ef-core) (2026-08-31): Temporal tables automatically track the full history of every row. EF Core 6+ has built-in support for configuring and querying temporal tables on SQL Server. - [EF Core DbContext: Configuration and Best Practices](https://milanjovanovic.tech/blog/dbcontext-configuration-best-practices) (2026-08-31): DbContext configuration decides how your app behaves under load: service lifetime, tracking defaults, pooling, retries, and interceptors. - [Audit Logging With EF Core Interceptors](https://milanjovanovic.tech/blog/audit-logging-ef-core) (2026-08-31): 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. - [Unit of Work Pattern With EF Core](https://milanjovanovic.tech/blog/unit-of-work-pattern-ef-core) (2026-08-30): EF Core DbContext already implements the Unit of Work pattern. But sometimes you need an explicit abstraction. - [Repository Pattern in C# With Entity Framework Core](https://milanjovanovic.tech/blog/repository-pattern-csharp) (2026-08-30): The repository pattern is one of the most debated patterns in .NET. This guide shows a clean EF Core implementation, explains why generic repositories… - [PostgreSQL Locking for .NET Developers: FOR UPDATE, SKIP LOCKED, and Advisory Locks](https://milanjovanovic.tech/blog/pessimistic-locking-ef-core-postgresql) (2026-08-30): PostgreSQL gives you row locks, SKIP LOCKED job queues, and advisory locks. Here is how to use each one from EF Core, with transaction patterns that avoid… - [Optimistic Concurrency With Postgres xmin in EF Core](https://milanjovanovic.tech/blog/ef-core-postgresql-xmin-concurrency) (2026-08-29): Two users edit the same row, and the last write wins without an error. PostgreSQL already versions every row internally through the xmin system column, and EF… - [Identity vs Sequence vs HiLo Key Generation in EF Core](https://milanjovanovic.tech/blog/ef-core-identity-sequence-hilo) (2026-08-29): Identity columns are the default, but they only hand you the id after the insert. HiLo assigns ids before SaveChanges, which lets you set foreign keys on… - [Cascade Delete in EF Core: Behaviors and Pitfalls](https://milanjovanovic.tech/blog/ef-core-cascade-delete) (updated 2026-07-14): DeleteBehavior in EF Core controls two different things: what EF does to tracked entities in memory, and what the database enforces with ON DELETE. - [Modeling Hierarchical Data in EF Core](https://milanjovanovic.tech/blog/ef-core-hierarchical-data) (2026-08-28): Categories with subcategories, org charts, and comment threads are all trees, and the obvious self-referencing entity is easy to write and hard to query… - [Custom Model Conventions in EF Core](https://milanjovanovic.tech/blog/ef-core-custom-conventions) (2026-08-28): Fifty entity configurations that all set the same string length and decimal precision are copy-paste. - [Computed Columns in EF Core](https://milanjovanovic.tech/blog/ef-core-computed-columns) (2026-08-28): Derived values calculated in C# drift out of sync the moment someone updates the database directly. - [Mapping JSON Columns in EF Core](https://milanjovanovic.tech/blog/ef-core-json-columns) (2026-08-27): Some data does not need its own table: settings blobs, address snapshots, flexible metadata. - [Mapping Enums in EF Core: Strings, Ints, and Native Postgres Enums](https://milanjovanovic.tech/blog/ef-core-enum-mapping) (2026-08-27): EF Core stores enums as ints by default, which breaks when someone reorders the enum. Storing them as strings survives refactoring, but it changes how ORDER BY… - [Composite Primary Keys in EF Core](https://milanjovanovic.tech/blog/ef-core-composite-keys) (2026-08-27): Composite primary keys look like a simple HasKey call, but they change how Find works, how relationships are configured, and how your indexes behave. - [Value Conversions in EF Core Explained](https://milanjovanovic.tech/blog/value-conversions-ef-core) (2026-08-26): 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… - [Table Per Hierarchy vs Table Per Type in EF Core](https://milanjovanovic.tech/blog/tph-vs-tpt-ef-core) (2026-08-26): TPH, TPT, and TPC map inheritance to different table and join shapes. Compare their constraints, generated SQL, and performance trade-offs before choosing a… - [Shadow Properties in EF Core Explained](https://milanjovanovic.tech/blog/shadow-properties-ef-core) (2026-08-26): 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… - [Owned Types in EF Core for DDD Value Objects](https://milanjovanovic.tech/blog/owned-types-ef-core-ddd) (2026-08-25): Value objects don't have identity. EF Core owned types let you persist them as part of the parent entity, with no ID and, for OwnsOne, no separate table. - [Configuring Entity Relationships in EF Core](https://milanjovanovic.tech/blog/entity-relationships-ef-core) (2026-08-25): EF Core supports one-to-one, one-to-many, and many-to-many relationships. Here is how to configure them with Fluent API and conventions. - [Complex Types in EF Core 8: What You Need to Know](https://milanjovanovic.tech/blog/complex-types-ef-core) (2026-08-25): 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… - [Seeding Data in EF Core: Strategies and Best Practices](https://milanjovanovic.tech/blog/seeding-data-ef-core) (2026-08-24): EF Core has several ways to seed data: HasData in model configuration, custom initialization logic, and SQL scripts. Here is when to use each strategy. - [How to Use EF Core With Multiple Databases](https://milanjovanovic.tech/blog/ef-core-multiple-databases) (2026-08-24): 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… - [EF Core Connection Resiliency and Retry Logic](https://milanjovanovic.tech/blog/ef-core-connection-resiliency) (2026-08-24): Cloud databases drop connections. EF Core's built-in retry logic handles transient failures automatically. - [Zero-Downtime Database Migrations With EF Core](https://milanjovanovic.tech/blog/zero-downtime-migrations-ef-core) (2026-08-23): Deploying database changes without downtime means old and new application code must both work against the same schema. - [How to Roll Back an EF Core Migration](https://milanjovanovic.tech/blog/ef-core-migration-rollback) (2026-08-23): 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… - [EF Core Migration Bundles for CI/CD Deployments](https://milanjovanovic.tech/blog/ef-core-migration-bundles) (2026-08-23): Calling Database.Migrate at startup means your schema changes run when the app boots, with app instances racing each other and failures taking production down. - [EF Core and PostgreSQL: Getting Started Guide](https://milanjovanovic.tech/blog/ef-core-postgresql-getting-started) (2026-08-22): PostgreSQL is an open-source database with features like JSONB, arrays, and full-text search. Here is how to set it up with EF Core using the Npgsql provider. - [Fixing "Cannot Write DateTime with Kind=Local" With Npgsql](https://milanjovanovic.tech/blog/ef-core-postgresql-datetime-utc-error) (2026-08-22): 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. - [EF Core Migrations Best Practices in Production](https://milanjovanovic.tech/blog/ef-core-migrations-best-practices) (2026-08-22): EF Core migrations are easy in development but tricky in production. Here are best practices for managing schema changes safely: idempotent scripts, migration… - [Fixing PendingModelChangesWarning in EF Core 9](https://milanjovanovic.tech/blog/ef-core-pending-model-changes-error) (2026-08-21): 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. - [Fixing "The Instance of Entity Type Cannot Be Tracked" in EF Core](https://milanjovanovic.tech/blog/ef-core-entity-already-tracked-error) (2026-08-21): The "instance of entity type cannot be tracked because another instance with the same key value is already being tracked" error means two objects with the same… - [EF Core Compiled Models for Faster Startup](https://milanjovanovic.tech/blog/ef-core-compiled-models) (2026-08-21): Large DbContexts pay a model-building tax on first use, and it grows with every entity you add. - [Find vs FirstOrDefault in EF Core](https://milanjovanovic.tech/blog/ef-core-find-vs-firstordefault) (2026-08-20): FindAsync and FirstOrDefaultAsync look interchangeable for loading by primary key, but Find checks the change tracker before touching the database. - [DbContext Pooling in EF Core: When It Helps and When It Bites](https://milanjovanovic.tech/blog/ef-core-dbcontext-pooling) (2026-08-20): AddDbContextPool can shave allocations off every request by recycling DbContext instances instead of creating them. - [AsNoTracking vs AsNoTrackingWithIdentityResolution](https://milanjovanovic.tech/blog/ef-core-asnotracking-identity-resolution) (2026-08-20): AsNoTracking is the standard advice for read-only EF Core queries, but it has a side effect: shared related entities get duplicated in memory, one copy per… - [Pagination in ASP.NET Core With EF Core](https://milanjovanovic.tech/blog/pagination-aspnetcore) (2026-08-19): Loading all records at once makes your API slow and spikes server memory. Here is how to implement offset and keyset pagination in ASP.NET Core with EF Core. - [How to Log SQL Queries Generated by EF Core](https://milanjovanovic.tech/blog/log-sql-queries-ef-core) (2026-08-19): Generated SQL exposes inefficient joins, repeated round trips, and missing predicates hidden by LINQ. - [Understanding the EF Core Change Tracker](https://milanjovanovic.tech/blog/change-tracker-ef-core) (2026-08-19): The EF Core change tracker records every entity you load or add, figures out what changed, and generates the right SQL on SaveChanges. - [N+1 Query Problem in EF Core and How to Fix It](https://milanjovanovic.tech/blog/n-plus-one-query-ef-core) (2026-08-18): The N+1 query problem is a common cause of slow EF Core code. One query loads the parents, then N queries load the children. Here is how to detect and fix it. - [EF Core Lazy Loading vs Eager Loading vs Explicit Loading](https://milanjovanovic.tech/blog/lazy-eager-explicit-loading-ef-core) (2026-08-18): EF Core gives you three ways to load related data: eager loading, explicit loading, and lazy loading. - [EF Core Query Performance: Avoid These Mistakes](https://milanjovanovic.tech/blog/ef-core-query-performance-mistakes) (2026-08-18): It is easy to write EF Core LINQ queries that generate slow SQL. Here are the most common performance mistakes and how to fix them: N+1 queries, over-fetching… - [EF Core Performance: Tips, Tricks, and Best Practices](https://milanjovanovic.tech/blog/ef-core-performance-guide) (updated 2026-08-02): Most EF Core slowdowns come from query shape, excess tracking, or round trips. Choose projections, split queries, batching, compiled models, and diagnostics. - [EF Core vs Dapper: When to Use Each](https://milanjovanovic.tech/blog/ef-core-vs-dapper) (updated 2026-07-14): 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. ## Messaging - [How I Use NATS JetStream as a Job Queue in .NET](https://milanjovanovic.tech/blog/nats-jetstream-job-queue-dotnet) (2026-07-10): My first job queue was a Redis list, and it had two ways to lose a job: a worker crash after LPOP, and a broker restart. - [RabbitMQ vs Kafka for .NET Applications](https://milanjovanovic.tech/blog/rabbitmq-vs-kafka-dotnet) (updated 2026-07-14): RabbitMQ deletes messages once consumed; Kafka keeps them and moves a cursor. That single design decision explains almost every difference between them… ## Microservices - [Microservices in .NET: Getting Started Guide](https://milanjovanovic.tech/blog/microservices-dotnet-getting-started) (updated 2026-07-14): A .NET microservice system needs more than separately deployed APIs: each service owns its data, communication survives partial failure, and traces cross every… ## Modular Monoliths - [When to Extract a Module Into a Microservice](https://milanjovanovic.tech/blog/when-to-extract-module-to-microservice) (2026-08-13): Extract a module too early and you lock unstable boundaries into network contracts. Wait too long and extraction becomes a multi-month rewrite. - [Strangler Fig Pattern for Modular Monolith Migration](https://milanjovanovic.tech/blog/strangler-fig-modular-monolith-migration) (2026-08-13): Big-bang rewrites fail for predictable reasons: they take longer than planned, the legacy system keeps changing underneath them, and the business sees nothing… - [Shared Kernel Pattern in Modular Monoliths](https://milanjovanovic.tech/blog/shared-kernel-pattern-modular-monolith) (2026-08-13): Modules need to share some code without becoming coupled. The shared kernel pattern defines a small, explicit set of shared types that all modules can depend… - [Schema-Per-Module vs Database-Per-Module: Which Data Isolation Strategy Should You Pick?](https://milanjovanovic.tech/blog/schema-per-module-vs-database-per-module) (2026-08-13): 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… - [Saga Pattern in a Modular Monolith](https://milanjovanovic.tech/blog/saga-pattern-modular-monolith) (2026-08-13): Placing an order touches Ordering, Inventory, Payment, and Shipping, and any step can fail after the previous ones already committed. - [Why the Outbox Pattern Solves the Dual-Write Problem](https://milanjovanovic.tech/blog/outbox-pattern-dual-write-problem) (2026-08-13): The dual-write problem leaves your database and message broker inconsistent when one write succeeds and the other fails. - [Defining Module Boundaries With Bounded Contexts](https://milanjovanovic.tech/blog/module-boundaries-bounded-contexts) (2026-08-13): 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… - [Event-Driven Communication Between Modules in .NET](https://milanjovanovic.tech/blog/event-driven-communication-modules) (2026-08-13): The Ordering module publishes an event, and Shipping and Notifications react without the publisher knowing they exist. - [How to Build a Modular Monolith in .NET Step by Step](https://milanjovanovic.tech/blog/build-modular-monolith-dotnet-step-by-step) (2026-08-13): 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… - [Modular Monolith Architecture in .NET: The Complete Guide](https://milanjovanovic.tech/blog/modular-monolith-architecture-dotnet) (updated 2026-07-14): A modular monolith keeps one deployment while enforcing business boundaries inside the codebase. - [Modular Monolith vs Microservices: How to Choose](https://milanjovanovic.tech/blog/modular-monolith-vs-microservices) (updated 2026-07-14): Modular Monoliths give you most of the benefits of microservices (loose coupling, independent modules, clear boundaries) without the operational complexity. ## Observability - [OpenTelemetry Collectors: The Agent + Gateway Pattern](https://milanjovanovic.tech/blog/opentelemetry-collector-agent-gateway) (2026-07-10): One OpenTelemetry Collector is easy. The design changes once your apps run on more than one machine: a small agent collector on every box, forwarding to one… - [Getting Started With OpenTelemetry in .NET](https://milanjovanovic.tech/blog/opentelemetry-dotnet-guide) (updated 2026-07-14): OpenTelemetry is the standard for distributed tracing, metrics, and logging. Here is how to instrument your .NET application and export telemetry to Jaeger and… ## Performance - [Async/Await Performance Pitfalls in .NET](https://milanjovanovic.tech/blog/async-await-performance-pitfalls) (updated 2026-07-14): Async improves throughput only while the work stays nonblocking. Sync-over-async, accidental serialization, unnecessary state machines, and unbounded fan-out… ## real time - [fetch-event-source: SSE With Bearer Tokens, Retries, and React](https://milanjovanovic.tech/blog/fetch-event-source) (2026-09-22): Native EventSource cannot send an Authorization header or a POST body. Use @microsoft/fetch-event-source to consume SSE with bearer tokens, validate responses… ## Resilience - [Polly v8: Resilience Pipelines Explained](https://milanjovanovic.tech/blog/polly-v8-resilience-pipelines) (updated 2026-07-14): Polly v8 replaced policies with resilience pipelines: a rewritten core with allocation-free execution, built-in telemetry, and one composition model instead of… ## Security - [JWT Authentication in ASP.NET Core: Complete Guide](https://milanjovanovic.tech/blog/jwt-authentication-aspnetcore) (updated 2026-07-14): JWT tokens are the standard way to authenticate APIs. This guide covers JWT authentication in ASP.NET Core: token generation, validation, refresh tokens, and… ## Testing - [Architecture Fitness Functions in .NET With ArchUnitNET](https://milanjovanovic.tech/blog/architecture-fitness-functions-archunitnet) (2026-07-25): An architecture rule nobody enforces depends on reviewers catching every violation. A fitness function turns it into a build failure that names the offending… - [Unit Testing Best Practices in .NET](https://milanjovanovic.tech/blog/unit-testing-best-practices-dotnet) (updated 2026-07-14): Poorly written unit tests break on every refactor and slow development down. These .NET practices cover test structure, naming, test data builders, mocking… ## Vertical Slice Architecture - [When to Choose Vertical Slice Architecture Over Layered Architecture](https://milanjovanovic.tech/blog/when-to-choose-vertical-slice-architecture) (2026-08-13): In a layered architecture, a query that returns one object touches seven types across four layers. - [Vertical Slice Architecture vs Clean Architecture](https://milanjovanovic.tech/blog/vertical-slice-vs-clean-architecture) (2026-08-13): Clean Architecture manages complexity through layer discipline. Vertical Slice Architecture manages it through feature isolation. - [Vertical Slice Architecture Folder Structure: From 5 to 50+ Features](https://milanjovanovic.tech/blog/vertical-slice-project-structure-dotnet) (2026-08-13): A concrete folder and solution layout for Vertical Slice Architecture in .NET, and how it evolves as you grow from 5 features to 50+. - [Vertical Slice Architecture With Carter in .NET](https://milanjovanovic.tech/blog/vertical-slice-architecture-carter-dotnet) (2026-08-13): Carter turns Minimal API endpoints into self-registering modules: each feature defines its routes, and app.MapCarter() wires them up at startup. - [Validation in Vertical Slice Architecture](https://milanjovanovic.tech/blog/validation-vertical-slice-architecture) (2026-08-13): In Vertical Slice Architecture, validation belongs in the slice. Co-locate validators with features and use a pipeline behavior to run them automatically. - [Testing Vertical Slices in .NET](https://milanjovanovic.tech/blog/testing-vertical-slices-dotnet) (2026-08-13): 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… - [Feature Folders in .NET: Organizing Code by Feature](https://milanjovanovic.tech/blog/feature-folders-dotnet) (2026-08-13): Feature folders organize code by feature instead of by technical concern (Controllers, Services, Models), so everything related to placing an order lives in… - [Cross-Cutting Concerns in Vertical Slice Architecture](https://milanjovanovic.tech/blog/cross-cutting-concerns-in-vertical-slice-architecture) (2026-08-13): One criticism of Vertical Slice Architecture is code duplication across slices. Here is how to handle cross-cutting concerns like validation, logging, and… - [Combining Vertical Slices With CQRS in .NET](https://milanjovanovic.tech/blog/combining-vertical-slices-cqrs) (2026-08-13): CQRS and Vertical Slice Architecture are a natural pair. Commands and queries are already separate, so putting each in its own slice makes them independent and… - [Vertical Slice Architecture in .NET: The Complete Guide](https://milanjovanovic.tech/blog/vertical-slice-architecture-dotnet) (updated 2026-07-14): Vertical Slice Architecture organizes code around behavior. Learn slice boundaries, validation, testing, and how VSA works with CQRS and Clean Architecture. - [The REPR Pattern in ASP.NET Core](https://milanjovanovic.tech/blog/repr-pattern-aspnetcore) (updated 2026-07-14): The REPR pattern (Request-Endpoint-Response) replaces bloated controllers with focused, single-purpose endpoints. ## The .NET Weekly newsletter archive - [Self-Hosting at Home With Cloudflare Tunnel](https://milanjovanovic.tech/blog/cloudflare-tunnel-hide-backend-ip) (2026-10-17): My Linux mini PC can run web apps, but CGNAT stops me from sharing them with a router port forward. - [Test Time-Dependent Code Without Waiting](https://milanjovanovic.tech/blog/test-time-dependent-code-without-waiting) (2026-10-10): I have time-dependent code in my application that I need to test. An invitation that expires after five minutes is a good example: I want to check the deadline… - [What It Actually Took to Port the GitHub Copilot Runtime to Rust](https://milanjovanovic.tech/blog/github-copilot-rust-migration-hype-vs-reality) (2026-10-03): GitHub ported the Copilot agent runtime from TypeScript to more than 800,000 lines of Rust, and the headlines credited one engineer and $120,000 in tokens. - [I Replaced a $120/Year SaaS With My Own App](https://milanjovanovic.tech/blog/speech-to-text-in-dotnet-with-assemblyai) (2026-09-26): I paid $120 a year for a transcription tool until a coding agent helped me get my own version running in under an hour. - [Adding an Index Made This Query Slower](https://milanjovanovic.tech/blog/when-postgres-picks-the-wrong-index) (2026-09-19): A query already had a usable index. Adding another index made Postgres choose a plan that discarded almost half a million rows to return ten. - [Let Postgres Enforce Tenant Isolation](https://milanjovanovic.tech/blog/postgres-row-level-security-with-ef-core) (2026-09-12): EF Core query filters can be bypassed. PostgreSQL row-level security enforces tenant isolation on reads and writes, if you connect with the right database role… - [Four Years of Writing Every Week](https://milanjovanovic.tech/blog/four-years-of-writing-every-week) (2026-09-05): Four years ago this week, the first issue of this newsletter landed in a few hundred inboxes. - [Your ASP.NET Core Endpoints Don't Have a Timeout](https://milanjovanovic.tech/blog/your-aspnetcore-endpoints-dont-have-a-timeout) (2026-08-29): ASP.NET Core doesn't enforce an application timeout on incoming requests by default. The built-in middleware can add one, but it only cancels RequestAborted. - [From 17ms to 0.04ms: How to Design the Right SQL Index](https://milanjovanovic.tech/blog/how-to-design-the-right-sql-index) (2026-08-22): What does a good SQL index look like? I seeded Postgres with 1 million comments and measured every indexing decision with EXPLAIN ANALYZE: a 17ms sequential… - [How Do You Build a Social Media Feed? (System Design)](https://milanjovanovic.tech/blog/how-do-you-build-a-social-media-feed-system-design) (2026-08-15): The home feed looks like the easiest feature in a social app: fetch posts from the accounts you follow, sort, return a page. - [Persisting a Rich Domain Model With EF Core](https://milanjovanovic.tech/blog/persisting-a-rich-domain-model-with-ef-core) (2026-08-08): Every time I show a rich domain model, someone tells me EF Core can't persist it without public setters and a public constructor. - [Should You Split That Into Microservices? Ask These 5 Questions First](https://milanjovanovic.tech/blog/should-you-split-that-into-microservices-ask-these-5-questions-first) (2026-08-01): Nobody regrets microservices on day one. The regret shows up eighteen months later, when the team is drowning in distributed-systems problems they never needed… - [The System Design Behind My New SaaS](https://milanjovanovic.tech/blog/the-system-design-behind-my-new-saas) (2026-07-25): I just shipped Katabench, and it's the most fun system I've ever built: it takes C# from strangers and runs it safely on servers I own. - [How I Migrated My Website to Cloudflare and Saved $228](https://milanjovanovic.tech/blog/how-i-migrated-my-website-to-cloudflare-and-saved-228-dollars) (2026-07-18): This website ran on Netlify for years, at $19 a month. Earlier this month I moved it to Cloudflare Pages: same repo, same GitHub Actions pipeline, zero… - [How to Test Vertical Slice Architecture](https://milanjovanovic.tech/blog/how-to-test-vertical-slice-architecture) (2026-07-11): The most common question I get about vertical slice architecture isn't about structure. It's "where do my tests go?" The layered-architecture testing habits… - [Build Your Own VPN With Tailscale](https://milanjovanovic.tech/blog/build-your-own-vpn-with-tailscale) (2026-07-04): Most of what runs on your servers was never meant to be public: databases, dashboards, admin panels, internal APIs. - [Getting Started With NATS JetStream in .NET](https://milanjovanovic.tech/blog/getting-started-with-nats-jetstream-in-dotnet) (2026-06-27): NATS almost never comes up when .NET developers talk about message queues, and that's a shame. - [The Modular Monolith Boundary I Couldn't Take Back](https://milanjovanovic.tech/blog/the-modular-monolith-boundary-i-couldnt-take-back) (2026-06-20): We built the system exactly the way a modular monolith is supposed to be built, and that's how I ended up with two modules I couldn't pull apart a year later. - [Building Dapr Workflows in .NET With Aspire](https://milanjovanovic.tech/blog/building-dapr-workflows-in-dotnet-with-aspire) (2026-06-13): Long-running business processes are hard to get right. Dapr Workflow lets you write them as plain C# code that survives crashes and restarts, and Aspire makes… - [DRY Is the Most Misunderstood Rule in Programming](https://milanjovanovic.tech/blog/dry-is-the-most-misunderstood-rule-in-programming) (2026-06-06): DRY was never about code that looks the same. It's about knowledge. Most of the tangled abstractions I've had to unwind started as a well-meaning attempt to… - [Union Types Are Finally Coming to C#](https://milanjovanovic.tech/blog/union-types-are-finally-coming-to-csharp) (2026-05-30): For years we faked union types with marker interfaces, base classes, and the OneOf library. - [How to Scale Long-Running API Requests](https://milanjovanovic.tech/blog/how-to-scale-long-running-api-requests) (2026-05-23): When a single API call takes minutes to finish, it punishes both your users and your server. - [When Your Use Case Half-Succeeds: Designing for Partial Failure in .NET](https://milanjovanovic.tech/blog/when-your-use-case-half-succeeds-designing-for-partial-failure-in-dotnet) (2026-05-16): A use case isn't a transaction. The moment it touches more than one system, you are dealing with partial failure. - [API Versioning Should Be Your Last Resort](https://milanjovanovic.tech/blog/api-versioning-should-be-your-last-resort) (2026-05-09): Most teams reach for v2 too early because they don't have a contract evolution strategy. Here's the API change management approach I prefer: evolve contracts… - [What Invariants Are (and Why a Domain Model Is the Best Place to Enforce Them)](https://milanjovanovic.tech/blog/what-invariants-are-and-why-a-domain-model-is-the-best-place-to-enforce-them) (2026-05-02): Most 'DDD-ish' code I review enforces business rules everywhere except in the model itself, so the same rule ends up duplicated across handlers and validators. - [The Test Pyramid Is a Lie (and What I Do Instead)](https://milanjovanovic.tech/blog/the-test-pyramid-is-a-lie-and-what-i-do-instead) (2026-04-25): The test pyramid made sense when integration tests meant a shared database server and a 20-minute build. It doesn't match how I build .NET systems in 2026. - [Why I Switched to Primary Constructors for DI in C#](https://milanjovanovic.tech/blog/why-i-switched-to-primary-constructors-for-di-in-csharp) (2026-04-18): I resisted primary constructors for a while. They felt like a shortcut that would cost me later. - [Implementing the Saga Pattern With Wolverine](https://milanjovanovic.tech/blog/implementing-the-saga-pattern-with-wolverine) (2026-04-11): Long-running business processes don't fit neatly into a single request. Wolverine's Saga support gives you a convention-based approach to orchestrating… - [Implementing the Inbox Pattern for Reliable Message Consumption](https://milanjovanovic.tech/blog/implementing-the-inbox-pattern-for-reliable-message-consumption) (2026-04-04): The Outbox pattern guarantees reliable publishing. But what about the consumer side? The Inbox pattern ensures each incoming message is processed exactly once… - [Getting Started With PgVector in .NET for Simple Vector Search](https://milanjovanovic.tech/blog/getting-started-with-pgvector-in-dotnet-for-simple-vector-search) (2026-03-28): Vector search doesn't require a dedicated vector database. PostgreSQL with pgvector gives you similarity search right next to your relational data. - [Scaling SignalR With a Redis Backplane](https://milanjovanovic.tech/blog/scaling-signalr-with-redis-backplane) (2026-03-21): SignalR connections are server-local. Scale out to multiple instances and messages stop reaching the right clients. - [Optimizing Bulk Database Updates in .NET: From Naive to Lightning-Fast](https://milanjovanovic.tech/blog/optimizing-bulk-database-updates-in-dotnet) (2026-03-14): Seven approaches to bulk-updating rows in PostgreSQL from .NET using Dapper and EF Core, from naive per-row updates to binary COPY. - [5 Architecture Tests You Should Add to Your .NET Projects](https://milanjovanovic.tech/blog/5-architecture-tests-you-should-add-to-your-dotnet-projects) (2026-03-07): Learn about five essential architecture tests that can help ensure the quality and maintainability of your .NET projects. - [How to Implement Two-Factor Authentication in ASP.NET Core](https://milanjovanovic.tech/blog/how-to-implement-two-factor-authentication-in-aspnetcore) (2026-02-28): Passwords alone are not enough. Learn how to implement Two-Factor Authentication in .NET using TOTP, QR codes, and the Otp.NET library, with a secure setup… - [Where Vertical Slices Fit Inside the Modular Monolith Architecture](https://milanjovanovic.tech/blog/where-vertical-slices-fit-inside-the-modular-monolith-architecture) (2026-02-21): Modular Monolith tells you how to split the system into modules. But it says nothing about how to organize code inside each module. - [How to Extract Structured Data From Images Using Ollama in .NET](https://milanjovanovic.tech/blog/how-to-extract-structured-data-from-images-using-ollama-in-dotnet) (2026-02-14): Vision models can do more than describe images. I used Ollama and Microsoft.Extensions.AI to extract structured receipt data into strongly typed C# objects… - [Integrate Keycloak with ASP.NET Core Using OAuth 2.0](https://milanjovanovic.tech/blog/integrate-keycloak-with-aspnetcore-using-oauth-2) (2026-02-07): Learn how to integrate Keycloak with your .NET 10 API using Docker, Swagger UI with OAuth 2.0 Authorization Code flow, and JWT validation. - [Containerize Your .NET Applications Without a Dockerfile](https://milanjovanovic.tech/blog/containerize-your-dotnet-applications-without-a-dockerfile) (2026-01-31): Learn how to containerize .NET applications without writing a single line of Dockerfile. The .NET SDK has built-in support for publishing directly to container… - [A Practical Demo of Zero-Downtime Migrations Using Password Hashing](https://milanjovanovic.tech/blog/a-practical-demo-of-zero-downtime-migrations-using-password-hashing) (2026-01-24): A practical demo of the zero-downtime migration pattern: run old + new password hash formats side-by-side, migrate users on login, and remove legacy safely. - [Solving the Distributed Cache Invalidation Problem with Redis and HybridCache](https://milanjovanovic.tech/blog/solving-the-distributed-cache-invalidation-problem-with-redis-and-hybridcache) (2026-01-17): Learn how to solve the distributed cache invalidation problem in .NET 9 by implementing a Redis Pub/Sub backplane to synchronize HybridCache instances across… - [Solving Message Ordering from First Principles](https://milanjovanovic.tech/blog/solving-message-ordering-from-first-principles) (2026-01-10): Per-aggregate ordering is what we really want. But queues with competing consumers make it surprisingly easy to break. - [The Urge to Build Something](https://milanjovanovic.tech/blog/the-urge-to-build-something) (2026-01-03): Looking at my contribution graph now, I can see the whole journey mapped out in squares of green. The startup dreams. The pivot to teaching. - [How to Build a High-Performance Cache Without External Libraries](https://milanjovanovic.tech/blog/how-to-build-a-high-performance-cache-without-external-libraries) (2025-12-27): Learn how to build a high-performance cache from scratch in .NET, moving from a simple ConcurrentDictionary to an optimized keyed-locking system. - [Server-Sent Events in ASP.NET Core and .NET 10](https://milanjovanovic.tech/blog/server-sent-events-in-aspnetcore-and-dotnet-10) (2025-12-20): ASP.NET Core 10 introduces native Server-Sent Events as a lightweight, HTTP-native alternative to SignalR for simple one-way real-time updates like dashboards… - [The New .slnx Solution Format (migration guide)](https://milanjovanovic.tech/blog/the-new-slnx-solution-format-migration-guide) (2025-12-13): See what changes in .slnx, how to convert your existing .sln, and what to watch out for in CI. - [DbContext is Not Thread-Safe: Parallelizing EF Core Queries the Right Way](https://milanjovanovic.tech/blog/dbcontext-is-not-thread-safe-parallelizing-ef-core-queries-the-right-way) (2025-12-06): Learn how to safely parallelize EF Core queries to improve performance by using IDbContextFactory to create isolated contexts, avoiding the thread-safety… - [Vertical Slice Architecture: Where Does the Shared Logic Live?](https://milanjovanovic.tech/blog/vertical-slice-architecture-where-does-the-shared-logic-live) (2025-11-29): Deciding where shared logic lives is the most critical moment in Vertical Slice Architecture adoption, because choosing wrong reintroduces the coupling you… - [The False Comfort of the "Happy Path": Decoupling Your Services](https://milanjovanovic.tech/blog/the-false-comfort-of-the-happy-path-decoupling-your-services) (2025-11-22): Coupling isn't just about code structure; it's about failure boundaries. Discover how to ensure your critical business logic survives when external… - [Exploring C# File-based Apps in .NET 10](https://milanjovanovic.tech/blog/exploring-csharp-file-based-apps-in-dotnet-10) (2025-11-15): With .NET 10, Microsoft introduced file-based apps, which give you the ability to write C# code in a single .cs file and run it directly, without any project… - [The Idempotent Consumer Pattern in .NET (And Why You Need It)](https://milanjovanovic.tech/blog/the-idempotent-consumer-pattern-in-dotnet-and-why-you-need-it) (2025-11-08): Distributed systems don't fail cleanly: they retry, duplicate, and occasionally fail. Here's how to design resilient message handlers in .NET with broker-level… - [What's New in EF Core 10: LeftJoin and RightJoin Operators in LINQ](https://milanjovanovic.tech/blog/whats-new-in-ef-core-10-leftjoin-and-rightjoin-operators-in-linq) (2025-11-01): .NET 10 finally adds proper LeftJoin and RightJoin methods to LINQ, replacing the complex GroupJoin + DefaultIfEmpty pattern with clean, readable code that… - [The Interview Question That Changed How I Think About System Design](https://milanjovanovic.tech/blog/the-interview-question-that-changed-how-i-think-about-system-design) (2025-10-25): Discover how a simple interview question about report generation reveals the difference between optimizing code and designing scalable systems, and why the… - [6 Steps for Setting Up a New .NET Project the Right Way](https://milanjovanovic.tech/blog/6-steps-for-setting-up-a-new-dotnet-project-the-right-way) (2025-10-18): Learn how to properly set up a new .NET project with EditorConfig for code consistency, Directory.Build.props for centralized configuration, central package… - [Building Fast Serverless APIs With Minimal APIs on AWS Lambda](https://milanjovanovic.tech/blog/building-fast-serverless-apis-with-minimal-apis-on-aws-lambda) (2025-10-11): Learn how to deploy ASP.NET Core Minimal APIs to AWS Lambda with just one library and a single line of code. - [Using Stored Procedures and Functions With EF Core and PostgreSQL](https://milanjovanovic.tech/blog/using-stored-procedures-and-functions-with-ef-core-and-postgresql) (2025-10-04): Learn how to use PostgreSQL stored procedures and functions with EF Core to handle complex queries, atomic operations with locking, and database-specific… - [Building Secure APIs with Role-Based Access Control in ASP.NET Core](https://milanjovanovic.tech/blog/building-secure-apis-with-role-based-access-control-in-aspnetcore) (2025-09-27): Learn how to implement Role-Based Access Control (RBAC) in ASP.NET Core with custom authorization handlers, permission-based policies, and clean extension… - [Distributed Locking in .NET: Coordinating Work Across Multiple Instances](https://milanjovanovic.tech/blog/distributed-locking-in-dotnet-coordinating-work-across-multiple-instances) (2025-09-20): Learn how to coordinate work across multiple application instances with distributed locking in .NET, preventing race conditions in scaled-out systems. - [Vertical Slice Architecture Is Easier Than You Think](https://milanjovanovic.tech/blog/vertical-slice-architecture-is-easier-than-you-think) (2025-09-13): Learn how Vertical Slice Architecture organizes .NET code by business features instead of technical layers, keeping related functionality together and making… - [Building Semantic Search with Amazon S3 Vectors and Semantic Kernel](https://milanjovanovic.tech/blog/building-semantic-search-with-amazon-s3-vectors-and-semantic-kernel) (2025-09-06): Learn how to add semantic search to your website using Amazon S3 Vectors - a new vector database service that's 90% cheaper than alternatives. - [Standalone Aspire Dashboard Setup for Distributed .NET Applications](https://milanjovanovic.tech/blog/standalone-aspire-dashboard-setup-for-distributed-dotnet-applications) (2025-08-30): Learn how to run the Aspire Dashboard as a standalone container for instant traces, logs, and metrics in your .NET applications. - [The Real Cost of Abstractions in .NET](https://milanjovanovic.tech/blog/the-real-cost-of-abstractions-in-dotnet) (2025-08-23): Not all abstractions are created equal. Some isolate real volatility and protect your system from change. - [Building Generative AI Applications With GitHub Models and .NET Aspire](https://milanjovanovic.tech/blog/building-generative-ai-applications-with-github-models-and-dotnet-aspire) (2025-08-16): Discover how to integrate AI into your .NET applications in under an hour using GitHub Models and .NET Aspire 9.4. - [The 5 Most Common REST API Design Mistakes (and How to Avoid Them)](https://milanjovanovic.tech/blog/the-5-most-common-rest-api-design-mistakes-and-how-to-avoid-them) (2025-08-09): Five REST API design mistakes I see all the time, with practical fixes. Use consistent resource naming, evolve contracts instead of bumping versions, add… - [How to Keep Your Data Boundaries Intact in a Modular Monolith](https://milanjovanovic.tech/blog/how-to-keep-your-data-boundaries-intact-in-a-modular-monolith) (2025-08-02): Want real boundaries in your modular monolith? This article shows how to enforce them at the database level using Postgres schemas, roles, and EF Core — so… - [Named Query Filters in EF 10 (multiple query filters per entity)](https://milanjovanovic.tech/blog/named-query-filters-in-ef-10-multiple-query-filters-per-entity) (2025-07-26): EF 10 introduces named query filters, letting you attach multiple filters to a single entity and disable specific ones without turning off all query filters. - [PDF Reporting in .NET With HTML Templates and PuppeteerSharp (and it's free)](https://milanjovanovic.tech/blog/pdf-reporting-in-dotnet-with-html-templates-and-puppeteersharp) (2025-07-19): Generate PDF reports in .NET using HTML templates and a headless browser. We'll explore Handlebars.NET and PuppeteerSharp, compare alternatives, and analyze… - [Global Error Handling in ASP.NET Core: From Middleware to Modern Handlers](https://milanjovanovic.tech/blog/global-error-handling-in-aspnetcore-from-middleware-to-modern-handlers) (2025-07-12): Learn How to handle errors globally in ASP.NET Core using middleware, IProblemDetailsService, and the new IExceptionHandler in .NET 8. - [Using .NET Aspire With the Docker Publisher](https://milanjovanovic.tech/blog/using-dotnet-aspire-with-the-docker-publisher) (2025-07-05): A practical walkthrough of using .NET Aspire's Docker publisher to generate Docker Compose files from C# code. - [Testcontainers Best Practices for .NET Integration Testing](https://milanjovanovic.tech/blog/testcontainers-best-practices-dotnet-integration-testing) (2025-06-28): Integration tests shouldn't rely on external infrastructure, but they also shouldn't mock everything away. - [Monitoring .NET Applications with OpenTelemetry and Grafana](https://milanjovanovic.tech/blog/monitoring-dotnet-applications-with-opentelemetry-and-grafana) (2025-06-21): Instrumenting your .NET apps with OpenTelemetry is easy. But what about actually seeing those metrics and traces in action? - [Run C# Scripts With dotnet run app.cs (No Project Files Needed)](https://milanjovanovic.tech/blog/run-csharp-scripts-with-dotnet-run-app-no-project-files-needed) (2025-06-14): With .NET 10, you can now run C# files directly. No project files, no Main method, just code. - [Debunking the "Filter Early, JOIN Later" SQL Performance Myth](https://milanjovanovic.tech/blog/debunking-the-filter-early-join-later-sql-performance-myth) (2025-06-07): That viral SQL performance tip about filtering before joining? It is complete nonsense. Here is why query optimizers make it irrelevant. - [YARP vs Nginx - A Quick Performance Comparison](https://milanjovanovic.tech/blog/yarp-vs-nginx-a-quick-performance-comparison) (2025-05-31): In this article, we will compare the performance of YARP and Nginx, two popular reverse proxy solutions. - [Building a Custom Domain Events Dispatcher in .NET](https://milanjovanovic.tech/blog/building-a-custom-domain-events-dispatcher-in-dotnet) (2025-05-24): Learn how to build a lightweight, in-process domain events dispatcher in .NET without external dependencies. - [CQRS Pattern the Way It Should've Been From the Start](https://milanjovanovic.tech/blog/cqrs-pattern-the-way-it-should-have-been-from-the-start) (2025-05-17): Learn how to implement CQRS in .NET without relying on MediatR. This guide walks you through a lightweight setup using simple interfaces, decorators, and DI —… - [From Anemic Models to Behavior-Driven Models: A Practical DDD Refactor in C#](https://milanjovanovic.tech/blog/from-anemic-models-to-behavior-driven-models-a-practical-ddd-refactor-in-csharp) (2025-05-10): A practical guide to transforming anemic domain models into behavior-rich aggregates in C# through incremental refactoring, enhancing code maintainability and… - [Event-Driven Architecture in .NET with RabbitMQ](https://milanjovanovic.tech/blog/event-driven-architecture-in-dotnet-with-rabbitmq) (2025-05-03): Learn how to implement flexible and resilient event-driven systems in .NET using RabbitMQ as a message broker with practical code examples for producers and… - [Refactoring Overgrown Bounded Contexts in Modular Monoliths](https://milanjovanovic.tech/blog/refactoring-overgrown-bounded-contexts-in-modular-monoliths) (2025-04-26): Learn how to untangle bloated services and split them into clean, modular bounded contexts in a .NET modular monolith - one practical refactor at a time. - [Understanding Microservices: Core Concepts and Benefits](https://milanjovanovic.tech/blog/understanding-microservices-core-concepts-and-benefits) (2025-04-19): What are microservices, and why might they be the right architectural choice for your organization? - [What is Vector Search? A Concise Guide](https://milanjovanovic.tech/blog/what-is-vector-search-a-concise-guide) (2025-04-12): Vector search finds information based on meaning rather than exact keywords, delivering more intuitive results by converting content into numerical vectors… - [MediatR and MassTransit Going Commercial: What This Means For You](https://milanjovanovic.tech/blog/mediatr-and-masstransit-going-commercial-what-this-means-for-you) (2025-04-05): MediatR, AutoMapper, and MassTransit are moving to commercial licenses after more than a decade of free open source. - [How .NET Aspire Simplifies Service Discovery](https://milanjovanovic.tech/blog/how-dotnet-aspire-simplifies-service-discovery) (2025-03-29): .NET Aspire revolutionizes distributed application development by simplifying service discovery through configuration-based approaches that eliminate the… - [Options Pattern Validation in ASP.NET Core With FluentValidation](https://milanjovanovic.tech/blog/options-pattern-validation-in-aspnetcore-with-fluentvalidation) (2025-03-22): Elevate your ASP.NET Core configuration with FluentValidation integration that catches configuration errors at startup, preventing silent failures and runtime… - [Streamlining .NET 9 Deployment With GitHub Actions and Azure](https://milanjovanovic.tech/blog/streamlining-dotnet-9-deployment-with-github-actions-and-azure) (2025-03-15): Build a robust, automated CI/CD pipeline for .NET 9 applications using GitHub Actions and Azure App Service to transform deployments from stressful events into… - [Better Request Tracing with User Context in ASP.NET Core](https://milanjovanovic.tech/blog/better-request-tracing-with-user-context-in-asp-net-core) (2025-03-08): Adding user context to request tracing in ASP.NET Core helps track issues and understand user behavior. - [Introduction to Dapr for .NET Developers](https://milanjovanovic.tech/blog/introduction-to-dapr-for-dotnet-developers) (2025-03-01): Explore how Dapr helps .NET developers build better microservices with standardized building blocks, practical code examples, and seamless integration with… - [Building a Better MediatR Publisher With Channels (and why you shouldn't)](https://milanjovanovic.tech/blog/building-a-better-mediatr-publisher-with-channels-and-why-you-shouldnt) (2025-02-22): Discover why MediatR's notification publishers block your application, and explore a Channel-based solution before reaching for a message queue. - [Understanding Cursor Pagination and Why It's So Fast (Deep Dive)](https://milanjovanovic.tech/blog/understanding-cursor-pagination-and-why-its-so-fast-deep-dive) (2025-02-15): Cursor-based pagination beats offset pagination as the pages get deeper. My tests show a 17x speedup on a million-record PostgreSQL dataset. - [Stop Conflating CQRS and MediatR](https://milanjovanovic.tech/blog/stop-conflating-cqrs-and-mediatr) (2025-02-08): The .NET ecosystem has fused CQRS and MediatR together, and that shortcut leads teams into unnecessary complexity. They solve different problems. - [Overriding Default HTTP Resilience Handlers in .NET](https://milanjovanovic.tech/blog/overriding-default-http-resilience-handlers-in-dotnet) (2025-02-01): Configure the standard resilience handler globally and it overrides the custom pipeline you added for a single HttpClient. - [Implementing AES Encryption With C#](https://milanjovanovic.tech/blog/implementing-aes-encryption-with-csharp) (2025-01-25): Learn how to implement secure AES encryption in C# to protect sensitive application data like API keys and passwords, with practical code examples covering… - [Scaling Monoliths: A Practical Guide for Growing Systems](https://milanjovanovic.tech/blog/scaling-monoliths-a-practical-guide-for-growing-systems) (2025-01-18): A well-designed monolith can scale remarkably well, despite industry trends pushing toward microservices. - [Working with LLMs in .NET using Microsoft.Extensions.AI](https://milanjovanovic.tech/blog/working-with-llms-in-dotnet-using-microsoft-extensions-ai) (2025-01-11): Microsoft.Extensions.AI gives you one interface for LLMs, so you can switch between Ollama, Azure, and OpenAI without changing application code. - [Unit Testing Clean Architecture Use Cases](https://milanjovanovic.tech/blog/unit-testing-clean-architecture-use-cases) (2025-01-04): A project I worked on required code coverage above 90%, which taught me that coverage is a starting point and not a measure of test quality. - [What Rewriting a 40-Year-Old Project Taught Me About Software Development](https://milanjovanovic.tech/blog/what-rewriting-a-40-year-old-project-taught-me-about-software-development) (2024-12-28): I spent four years rewriting a 40-year-old manufacturing system written in APL while the $10M business it powered kept running. - [Scheduling Background Jobs With Quartz in .NET (advanced concepts)](https://milanjovanovic.tech/blog/scheduling-background-jobs-with-quartz-in-dotnet-advanced-concepts) (2024-12-21): Quartz.NET is a powerful job scheduling library, but integrating it properly with ASP.NET Core requires careful consideration. - [Internal vs. Public APIs in Modular Monoliths](https://milanjovanovic.tech/blog/internal-vs-public-apis-in-modular-monoliths) (2024-12-14): Every article about modular monoliths tells you to use public APIs between modules, but few explain why they exist or how to design them. - [Central Package Management in .NET - Simplify NuGet Dependencies](https://milanjovanovic.tech/blog/central-package-management-in-net-simplify-nuget-dependencies) (2024-12-07): You open a large solution and find that every project uses a different version of the same package. - [Implementing the Saga Pattern With MassTransit](https://milanjovanovic.tech/blog/implementing-the-saga-pattern-with-masstransit) (2024-11-30): Long-running business processes span multiple services, and two-phase commit holds database locks across all of them. - [Building Async APIs in ASP.NET Core - The Right Way](https://milanjovanovic.tech/blog/building-async-apis-in-aspnetcore-the-right-way) (2024-11-23): Not every API request needs to finish right away. Learn how to build better APIs by moving long-running tasks to the background. - [HybridCache in ASP.NET Core - New Caching Library](https://milanjovanovic.tech/blog/hybrid-cache-in-aspnetcore-new-caching-library) (2024-11-16): HybridCache in .NET 9 combines fast in-memory caching with distributed caching, solving problems like cache stampede while adding tag-based invalidation. - [Functional Programming in C#: The Practical Parts](https://milanjovanovic.tech/blog/functional-programming-in-csharp-the-practical-parts) (2024-11-09): Functional programming patterns can make your C# code safer and more maintainable, without getting lost in academic theory. - [Clean Architecture: The Missing Chapter](https://milanjovanovic.tech/blog/clean-architecture-the-missing-chapter) (2024-11-02): Clean Architecture's famous diagram is often misinterpreted as a project structure, scattering business logic across artificial technical layers. - [Implementing Idempotent REST APIs in ASP.NET Core](https://milanjovanovic.tech/blog/implementing-idempotent-rest-apis-in-aspnetcore) (2024-10-26): Learn how to implement idempotency in ASP.NET Core Web APIs to improve reliability and prevent duplicate operations in distributed systems. - [Problem Details for ASP.NET Core APIs](https://milanjovanovic.tech/blog/problem-details-for-aspnetcore-apis) (2024-10-19): Problem Details gives your ASP.NET Core APIs consistent, machine-readable error responses that comply with RFC 9457. - [Scaling the Outbox Pattern (2B+ messages per day)](https://milanjovanovic.tech/blog/scaling-the-outbox-pattern) (2024-10-12): Learn how to supercharge your Outbox pattern implementation, scaling to 32,500 messages per second. - [Implementing the Outbox Pattern](https://milanjovanovic.tech/blog/implementing-the-outbox-pattern) (2024-10-05): Discover how the Outbox pattern solves the dual-write problem in distributed systems, ensuring data consistency between your database and external components. - [Breaking It Down: How to Migrate Your Modular Monolith to Microservices](https://milanjovanovic.tech/blog/breaking-it-down-how-to-migrate-your-modular-monolith-to-microservices) (2024-09-28): Moving from a modular monolith to microservices buys you independent scaling and deployment, and costs you a distributed system. - [How I Implemented Full-Text Search On My Website](https://milanjovanovic.tech/blog/how-i-implemented-full-text-search-on-my-website) (2024-09-21): This article walks you through how I used Lunr.js to add powerful search capabilities to a Next.js static site, dealing with challenges like client-side… - [.NET Aspire: A Game-Changer for Cloud-Native Development?](https://milanjovanovic.tech/blog/dotnet-aspire-a-game-changer-for-cloud-native-development) (2024-09-14): .NET Aspire promises to simplify cloud-native .NET development, but does it live up to the hype? - [Refit in .NET: Building Robust API Clients in C#](https://milanjovanovic.tech/blog/refit-in-dotnet-building-robust-api-clients-in-csharp) (2024-09-07): Refit turns your HTTP API into a strongly typed C# interface, so you stop hand-writing HttpClient boilerplate. - [Introduction to Event Sourcing for .NET Developers](https://milanjovanovic.tech/blog/introduction-to-event-sourcing-for-net-developers) (2024-08-31): Discover event sourcing in .NET through a beginner's eyes. Explore core concepts, benefits, and real-world challenges. - [Screaming Architecture](https://milanjovanovic.tech/blog/screaming-architecture) (2024-08-24): If you were to glance at the folder structure of your system, could you tell what the system is about? - [Complete Guide to Amazon SQS and Amazon SNS With MassTransit](https://milanjovanovic.tech/blog/complete-guide-to-amazon-sqs-and-amazon-sns-with-masstransit) (2024-08-17): In this article, we'll explore how to use Amazon SQS and SNS for asynchronous messaging in .NET applications. - [5 EF Core Features You Need To Know](https://milanjovanovic.tech/blog/5-ef-core-features-you-need-to-know) (2024-08-10): EF Core is powerful, and knowing a few key features can save you lots of time and frustration. - [Improving Code Quality in C# With Static Code Analysis](https://milanjovanovic.tech/blog/improving-code-quality-in-csharp-with-static-code-analysis) (2024-08-03): Static code analysis helps you build secure, maintainable, and high-quality C# code. In this week's newsletter, we'll explore how to integrate it into your… - [Simple Messaging in .NET With Redis Pub/Sub](https://milanjovanovic.tech/blog/simple-messaging-in-dotnet-with-redis-pubsub) (2024-07-27): Redis is a popular choice for caching data, but its capabilities go far beyond that. One of its lesser-known features is Pub/Sub support. - [Testing Modular Monoliths: System Integration Testing](https://milanjovanovic.tech/blog/testing-modular-monoliths-system-integration-testing) (2024-07-20): System integration testing is the perfect testing approach for modular monoliths. It's an approach to testing the interactions between various modules within a… - [Building Your First Use Case With Clean Architecture](https://milanjovanovic.tech/blog/building-your-first-use-case-with-clean-architecture) (2024-07-13): This is a question I often hear: how do I design my use case with Clean Architecture? In this article, we'll explore a practical example of how to apply Clean… - [Service Discovery in Microservices With .NET and Consul](https://milanjovanovic.tech/blog/service-discovery-in-microservices-with-net-and-consul) (2024-07-06): Service discovery is a pattern that allows developers to use logical names to refer to external services, instead of physical IP addresses and ports. - [Flexible PDF Reporting in .NET Using Razor Views](https://milanjovanovic.tech/blog/flexible-pdf-reporting-in-net-using-razor-views) (2024-06-29): In this article, we'll explore the power of using Razor views for flexible PDF reporting in .NET. - [What You Need To Know About EF Core Bulk Updates](https://milanjovanovic.tech/blog/what-you-need-to-know-about-ef-core-bulk-updates) (2024-06-22): EF Core 7 introduced two powerful new methods, ExecuteUpdate and ExecuteDelete. However, there's an important caveat: these bulk operations bypass the EF Core… - [From Transaction Scripts to Domain Models: A Refactoring Journey](https://milanjovanovic.tech/blog/from-transaction-scripts-to-domain-models-a-refactoring-journey) (2024-06-15): Transaction Scripts organizes business logic by procedures where each procedure handles a single request from the presentation. - [Caching in ASP.NET Core: Improving Application Performance](https://milanjovanovic.tech/blog/caching-in-aspnetcore-improving-application-performance) (2024-06-08): Caching is one of the simplest techniques to significantly improve your application's performance. - [Vertical Slice Architecture: Structuring Vertical Slices](https://milanjovanovic.tech/blog/vertical-slice-architecture-structuring-vertical-slices) (2024-06-01): Are you tired of organizing your project across layers? Vertical Slice Architecture is a compelling alternative to traditional layered architectures. - [Shift Left With Architecture Testing in .NET](https://milanjovanovic.tech/blog/shift-left-with-architecture-testing-in-dotnet) (2024-05-25): In this newsletter, we'll explore how architecture testing can safeguard our project's architecture. - [EF Core Migrations: A Detailed Guide](https://milanjovanovic.tech/blog/efcore-migrations-a-detailed-guide) (2024-05-18): In this newsletter, we'll break down the essentials of EF Migrations. We'll explore creating migrations, SQL scripts, applying migrations, migration tooling… - [Building Resilient Cloud Applications With .NET](https://milanjovanovic.tech/blog/building-resilient-cloud-applications-with-dotnet) (2024-05-11): By designing your applications with resilience in mind, you can create robust and reliable systems, even when the going gets tough. - [Implementing API Gateway Authentication With YARP](https://milanjovanovic.tech/blog/implementing-api-gateway-authentication-with-yarp) (2024-05-04): In this newsletter, we'll explore how you can implement API gateway authentication using YARP (Yet Another Reverse Proxy), a powerful and flexible reverse… - [Request-Response Messaging Pattern With MassTransit](https://milanjovanovic.tech/blog/request-response-messaging-pattern-with-masstransit) (2024-04-27): When building distributed systems with .NET, direct calls between services can create tight coupling. - [Introduction to Distributed Tracing With OpenTelemetry in .NET](https://milanjovanovic.tech/blog/introduction-to-distributed-tracing-with-opentelemetry-in-dotnet) (2024-04-20): Distributed systems offer flexibility but introduce complexity, making troubleshooting a headache. - [A Clever Way To Implement Pessimistic Locking in EF Core](https://milanjovanovic.tech/blog/a-clever-way-to-implement-pessimistic-locking-in-ef-core) (2024-04-13): Sometimes, especially in high-traffic scenarios, you need to ensure only one process can modify a piece of data at a time. - [Master Claims Transformation for Flexible ASP.NET Core Authorization](https://milanjovanovic.tech/blog/master-claims-transformation-for-flexible-aspnetcore-authorization) (2024-04-06): Claims-based authorization mechanisms are central to modern authorization in ASP.NET Core. - [Horizontally Scaling ASP.NET Core APIs With YARP Load Balancing](https://milanjovanovic.tech/blog/horizontally-scaling-aspnetcore-apis-with-yarp-load-balancing) (2024-03-30): When a single server reaches its limits, performance degrades, leading to slow response times, errors, or complete downtime. - [Fast SQL Bulk Inserts With C# and EF Core](https://milanjovanovic.tech/blog/fast-sql-bulk-inserts-with-csharp-and-ef-core) (2024-03-23): Explore various methods for fast bulk inserts in SQL with C# and EF Core, highlighting techniques like Dapper, EF Core optimizations, EF Core Bulk Extensions… - [Implementing Soft Delete With EF Core](https://milanjovanovic.tech/blog/implementing-soft-delete-with-ef-core) (2024-03-16): A soft delete is a data persistence strategy that prevents the permanent deletion of records from your database. - [What Is a Modular Monolith?](https://milanjovanovic.tech/blog/what-is-a-modular-monolith) (2024-03-09): Modular monoliths blend the simplicity and robustness of traditional monolithic applications with the flexibility and scalability of microservices. - [Lightweight In-Memory Message Bus Using .NET Channels](https://milanjovanovic.tech/blog/lightweight-in-memory-message-bus-using-dotnet-channels) (2024-03-02): Suppose you're building a modular monolith, a type of software architecture where different components are organized into loosely coupled modules. - [Automatically Register Minimal APIs in ASP.NET Core](https://milanjovanovic.tech/blog/automatically-register-minimal-apis-in-aspnetcore) (2024-02-24): In ASP.NET Core applications using Minimal APIs, registering each API endpoint with app.MapGet, app.MapPost, etc. can introduce repetitive code. - [Using Scoped Services From Singletons in ASP.NET Core](https://milanjovanovic.tech/blog/using-scoped-services-from-singletons-in-aspnetcore) (2024-02-17): Did you ever need to inject a scoped service into a singleton service? I'll explain how you can solve this problem and safely use scoped services from within… - [Getting the Current User in Clean Architecture](https://milanjovanovic.tech/blog/getting-the-current-user-in-clean-architecture) (2024-02-10): The applications you build serve your users (customers), to help them solve some problems. - [How I Made My EF Core Query 3.42x Faster With Batching](https://milanjovanovic.tech/blog/how-i-made-my-efcore-query-faster-with-batching) (2024-02-03): EF Core is a fantastic ORM if you're building .NET applications. Today, I'll show you a simple idea I used to get an almost 4x performance improvement. - [How to Build a URL Shortener With .NET](https://milanjovanovic.tech/blog/how-to-build-a-url-shortener-with-dotnet) (2024-01-27): A URL shortener is a simple yet powerful tool that converts long URLs into more manageable, shorter versions. - [Balancing Cross-Cutting Concerns in Clean Architecture](https://milanjovanovic.tech/blog/balancing-cross-cutting-concerns-in-clean-architecture) (2024-01-20): Cross-cutting concerns are application-level functionalities that affect the entire application and span several layers. - [Extending HttpClient With Delegating Handlers in ASP.NET Core](https://milanjovanovic.tech/blog/extending-httpclient-with-delegating-handlers-in-aspnetcore) (2024-01-13): Delegating handlers are like ASP.NET Core middleware. Except they work with the HttpClient. I'll show you how to work with delegating handlers - [Using MassTransit with RabbitMQ and Azure Service Bus](https://milanjovanovic.tech/blog/using-masstransit-with-rabbitmq-and-azure-service-bus) (2024-01-06): MassTransit is an open-source distributed application framework for .NET. It provides a messaging abstraction on top of the supported message transports. - [API Versioning in ASP.NET Core](https://milanjovanovic.tech/blog/api-versioning-in-aspnetcore) (2023-12-30): API versioning allows your API to evolve independently from the clients using it. I'll show you how to implement API versioning in ASP.NET Core. - [Value Objects in .NET (DDD Fundamentals)](https://milanjovanovic.tech/blog/value-objects-in-dotnet-ddd-fundamentals) (2023-12-23): Value Objects are one of the building blocks of Domain-Driven Design. Today, I'll show you some best practices for implementing Value Objects. - [5 Serilog Best Practices For Better Structured Logging](https://milanjovanovic.tech/blog/5-serilog-best-practices-for-better-structured-logging) (2023-12-16): Serilog is a structured logging library for .NET. It's also my preferred logging library in the projects I'm developing. - [Modular Monolith Data Isolation](https://milanjovanovic.tech/blog/modular-monolith-data-isolation) (2023-12-09): Modular monoliths are an architectural approach that's becoming very popular. They combine the benefits of modularity and monolithic design. - [Global Error Handling in ASP.NET Core 8](https://milanjovanovic.tech/blog/global-error-handling-in-aspnetcore-8) (2023-12-02): Exceptions are for exceptional situations, but they will inevitably happen and you need to handle them. - [5 Awesome C# Refactoring Tips](https://milanjovanovic.tech/blog/5-awesome-csharp-refactoring-tips) (2023-11-25): Refactoring is restructuring existing code without changing its behavior. One change does little, but a sequence of refactors produces a significant… - [How To Use EF Core Interceptors](https://milanjovanovic.tech/blog/how-to-use-ef-core-interceptors) (2023-11-18): EF Core is my favorite ORM for .NET applications, but many of its fantastic features go unnoticed. - [How To Easily Create PDF Documents in ASP.NET Core](https://milanjovanovic.tech/blog/how-to-easily-create-pdf-documents-in-aspnetcore) (2023-11-11): Reporting is essential for business applications like e-commerce, shipping, fintech, etc. One of the most popular document formats for reporting purposes is… - [Vertical Slice Architecture](https://milanjovanovic.tech/blog/vertical-slice-architecture) (2023-11-04): Layered architectures are the foundation of many software systems, but they organize the system around technical layers, and the cohesion between layers is low. - [Functional Error Handling in .NET With the Result Pattern](https://milanjovanovic.tech/blog/functional-error-handling-in-dotnet-with-the-result-pattern) (2023-10-28): How should you handle errors in your code? Exceptions are for exceptional situations, and using them for flow control makes the code harder to reason about. - [CQRS Pattern With MediatR](https://milanjovanovic.tech/blog/cqrs-pattern-with-mediatr) (2023-10-21): The CQRS pattern separates the writes and reads in the application, and that separation can be logical or physical. - [Improving ASP.NET Core Dependency Injection With Scrutor](https://milanjovanovic.tech/blog/improving-aspnetcore-dependency-injection-with-scrutor) (2023-10-14): ASP.NET Core's built-in DI system sometimes needs a little help to achieve more advanced scenarios. - [Getting Started With NServiceBus in .NET](https://milanjovanovic.tech/blog/getting-started-with-nservicebus-in-dotnet) (2023-10-07): NServiceBus is a feature-rich messaging framework supporting many different message transports. Its basic building blocks are messages and endpoints. - [CQRS Validation with MediatR Pipeline and FluentValidation](https://milanjovanovic.tech/blog/cqrs-validation-with-mediatr-pipeline-and-fluentvalidation) (2023-09-30): I consider input and business validation differently, and each deserves a specific solution. - [Monolith to Microservices: How a Modular Monolith Helps](https://milanjovanovic.tech/blog/monolith-to-microservices-how-a-modular-monolith-helps) (2023-09-23): You start building a beautiful monolith system, maybe a modular monolith. The system grows, cracks begin to appear, and at last you decide it's time to migrate… - [Feature Flags in .NET and How I Use Them for A/B Testing](https://milanjovanovic.tech/blog/feature-flags-in-dotnet-and-how-i-use-them-for-ab-testing) (2023-09-16): Feature flags let you wrap a feature in a conditional statement and toggle it on or off at runtime, without redeploying the code. - [Solving Race Conditions With EF Core Optimistic Locking](https://milanjovanovic.tech/blog/solving-race-conditions-with-ef-core-optimistic-locking) (2023-09-09): I'll challenge you to spot the race condition in a method for reserving a booking, where you can't have two overlapping reservations for the same dates. - [Testcontainers - Integration Testing Using Docker In .NET](https://milanjovanovic.tech/blog/testcontainers-integration-testing-using-docker-in-dotnet) (2023-09-02): Unit tests are helpful, but you can't be fully confident in your application without integration tests. - [Orchestration vs Choreography](https://milanjovanovic.tech/blog/orchestration-vs-choreography) (2023-08-26): Designing effective communication between services is one of the challenges of working with distributed systems. More centralization or less? - [Advanced Rate Limiting Use Cases In .NET](https://milanjovanovic.tech/blog/advanced-rate-limiting-use-cases-in-dotnet) (2023-08-19): Rate limiting is about restricting the number of requests to your application. It improves security, guards against DDoS attacks, and prevents overloading your… - [Mastering Dapper Relationship Mappings](https://milanjovanovic.tech/blog/mastering-dapper-relationship-mappings) (2023-08-12): Dapper is a lightweight object-relational mapper in .NET, easy to use and fast at the same time. - [Modular Monolith Communication Patterns](https://milanjovanovic.tech/blog/modular-monolith-communication-patterns) (2023-08-05): Modular monoliths give you the logical architecture of microservices without the operational complexity. - [Why Clean Architecture Is Great For Complex Projects](https://milanjovanovic.tech/blog/why-clean-architecture-is-great-for-complex-projects) (2023-07-29): I've been using Clean Architecture for 6+ years on large scale applications serving thousands of customers. - [How To Use Domain Events To Build Loosely Coupled Systems](https://milanjovanovic.tech/blog/how-to-use-domain-events-to-build-loosely-coupled-systems) (2023-07-22): Domain events are a Domain-Driven Design tactical pattern for building loosely coupled systems. - [8 Tips To Write Clean Code](https://milanjovanovic.tech/blog/8-tips-to-write-clean-code) (2023-07-15): Clean code is code that's easy to read, maintain, and understand. It's a skill you can learn with deliberate practice. - [Implementing an API Gateway For Microservices With YARP](https://milanjovanovic.tech/blog/implementing-an-api-gateway-for-microservices-with-yarp) (2023-07-08): A client application shouldn't need to know about every service in your system. An API gateway acts as a reverse proxy, accepting API calls and forwarding them… - [Response Compression In ASP.NET Core](https://milanjovanovic.tech/blog/response-compression-in-aspnetcore) (2023-07-01): Reducing the size of your API responses can noticeably improve performance. Response compression in ASP.NET Core takes two method calls, and in the best case… - [Adding Real-Time Functionality To .NET Applications With SignalR](https://milanjovanovic.tech/blog/adding-real-time-functionality-to-dotnet-applications-with-signalr) (2023-06-24): If you need real-time functionality in .NET, there's one library you will most likely reach for: SignalR. - [Refactoring From an Anemic Domain Model To a Rich Domain Model](https://milanjovanovic.tech/blog/refactoring-from-an-anemic-domain-model-to-a-rich-domain-model) (2023-06-17): Is the anemic domain model an antipattern? It works great in simple applications, but with rich business logic the important rules end up scattered all over… - [The Right Way To Use HttpClient In .NET](https://milanjovanovic.tech/blog/the-right-way-to-use-httpclient-in-dotnet) (2023-06-10): The easy way to make HTTP requests in .NET is HttpClient. Unfortunately, it's easy to misuse, and port exhaustion and DNS behavior are some of the most common… - [Scheduling Background Jobs With Quartz.NET](https://milanjovanovic.tech/blog/scheduling-background-jobs-with-quartz-net) (2023-06-03): How can you create a recurring background job in .NET? Quartz.NET is a full-featured, open source job scheduling system that can be used from smallest apps to… - [How To Build a CI/CD Pipeline With GitHub Actions And .NET](https://milanjovanovic.tech/blog/how-to-build-ci-cd-pipeline-with-github-actions-and-dotnet) (2023-05-27): Imagine being able to automatically build, test, and deploy your .NET applications with every code change. GitHub Actions are completely free and simple to use. - [Multi-Tenant Applications With EF Core](https://milanjovanovic.tech/blog/multi-tenant-applications-with-ef-core) (2023-05-20): One application serves multiple customers, while keeping their data isolated. You can approach multi-tenancy with a single database and logical isolation, or… - [Visualize Your Software Architecture With The C4 Model](https://milanjovanovic.tech/blog/visualize-your-software-architecture-with-the-c4-model) (2023-05-13): Most software architecture diagrams I've seen are a total mess. The C4 model is a lightweight, standard way to describe your system, with four diagram types… - [Enforcing Software Architecture With Architecture Tests](https://milanjovanovic.tech/blog/enforcing-software-architecture-with-architecture-tests) (2023-05-06): When deadlines are tight and you start cutting corners, that beautiful software architecture you built crumbles like a house of cards. So how do you enforce it? - [Health Checks In ASP.NET Core For Monitoring Your Applications](https://milanjovanovic.tech/blog/health-checks-in-asp-net-core) (2023-04-29): With distributed systems growing in complexity, it's getting harder to monitor the health of our applications. That's where health checks come in. - [Idempotent Consumer - Handling Duplicate Messages](https://milanjovanovic.tech/blog/idempotent-consumer-handling-duplicate-messages) (2023-04-22): What happens when a message is retried in an event-driven system? The worst case scenario is that the message is processed twice, and the side effects can be… - [EF Core Raw SQL Queries](https://milanjovanovic.tech/blog/ef-core-raw-sql-queries) (2023-04-15): EF7 introduced support for returning scalar types using SQL queries. And now we're getting support for querying unmapped types with raw SQL queries in EF8. - [How To Use Rate Limiting In ASP.NET Core](https://milanjovanovic.tech/blog/how-to-use-rate-limiting-in-aspnet-core) (2023-04-08): Rate limiting is a technique to limit the number of requests to a server or an API. ASP.NET Core 7 has a built-in rate limiter middleware that's easy to… - [Implementing The Saga Pattern With Rebus And RabbitMQ](https://milanjovanovic.tech/blog/implementing-the-saga-pattern-with-rebus-and-rabbitmq) (2023-04-01): Designing long-lived processes in a distributed environment is an interesting engineering challenge. - [How To Publish MediatR Notifications In Parallel](https://milanjovanovic.tech/blog/how-to-publish-mediatr-notifications-in-parallel) (2023-03-25): MediatR supports the publish-subscribe pattern with notifications, and until recently the handlers subscribing to an INotification could only execute serially… - [Creating Data-Driven Tests With xUnit](https://milanjovanovic.tech/blog/creating-data-driven-tests-with-xunit) (2023-03-18): Data-driven testing is where test data comes from an external source, which is why it's also known as parameterized testing. - [Using Multiple EF Core DbContexts In a Single Application](https://milanjovanovic.tech/blog/using-multiple-ef-core-dbcontext-in-single-application) (2023-03-11): It's common to have only one DbContext for the entire application. But what if you need multiple DbContexts? - [How To Apply Functional Programming In C#](https://milanjovanovic.tech/blog/how-to-apply-functional-programming-in-csharp) (2023-03-04): Although C# is object-oriented, it has plenty of functional features: pattern matching, switch expressions, records. - [Outbox Pattern For Reliable Microservices Messaging](https://milanjovanovic.tech/blog/outbox-pattern-for-reliable-microservices-messaging) (2023-02-25): How can you implement reliable communication between components in a distributed system? The Outbox pattern is an elegant solution, giving you transactional… - [Structured Logging In ASP.NET Core With Serilog](https://milanjovanovic.tech/blog/structured-logging-in-asp-net-core-with-serilog) (2023-02-18): Serilog is a popular .NET logging library, and what makes it unique is structured logging out of the box. - [Messaging Made Easy With Azure Service Bus](https://milanjovanovic.tech/blog/messaging-made-easy-with-azure-service-bus) (2023-02-11): Loose coupling is an important quality in a distributed system, and you need a messaging system to get it. Azure Service Bus is an excellent choice. - [Working With Transactions In EF Core](https://milanjovanovic.tech/blog/working-with-transactions-in-ef-core) (2023-02-04): Every software engineer working with SQL databases needs to know about transactions. And since the database is usually abstracted by an ORM like EF Core, it's… - [How To Implement API Key Authentication In ASP.NET Core](https://milanjovanovic.tech/blog/how-to-implement-api-key-authentication-in-aspnet-core) (2023-01-28): In this week's newsletter I want to show you how to implement API Key authentication in ASP.NET Core, with the API key passed in a request header. - [C# Yield Return Statement](https://milanjovanovic.tech/blog/csharp-yield-return-statement) (2023-01-21): In this week's newsletter I want to talk about the yield keyword in C#. The yield keyword tells the compiler that the method is an iterator block, which… - [Unleash EF Core Performance With Compiled Queries](https://milanjovanovic.tech/blog/unleash-ef-core-performance-with-compiled-queries) (2023-01-14): In this week's newsletter I want to introduce you to an interesting EF Core feature called Compiled Queries. - [Adding Validation To The Options Pattern In ASP.NET Core](https://milanjovanovic.tech/blog/adding-validation-to-the-options-pattern-in-asp-net-core) (2023-01-07): In this week's newsletter I will show you how to add validation to the strongly typed configuration objects injected with IOptions. - [How To Be a Better Software Engineer In 2023](https://milanjovanovic.tech/blog/how-to-be-a-better-software-engineer-in-2023) (2022-12-31): In this week's newsletter I will share 5 simple tips on how you can be a better software engineer in 2023. - [Clean Architecture And The Benefits Of Structured Software Design](https://milanjovanovic.tech/blog/clean-architecture-and-the-benefits-of-structured-software-design) (2022-12-24): It's easy to get swayed by the latest trends, and lose sight of the architectural principles that really matter. - [Fast Document Database In .NET With Marten](https://milanjovanovic.tech/blog/fast-document-database-in-net-with-marten) (2022-12-17): Did you know you can turn PostgreSQL into a fully-fledged Document database? Marten is a .NET library that lets you use PostgreSQL as both a document database… - [How To Structure Minimal APIs](https://milanjovanovic.tech/blog/how-to-structure-minimal-apis) (2022-12-10): Minimal APIs were introduced to remove some of the ceremony of creating traditional APIs with controllers. - [Running Background Tasks In ASP.NET Core](https://milanjovanovic.tech/blog/running-background-tasks-in-asp-net-core) (2022-12-03): In this week's newsletter we will talk about running background tasks in ASP.NET Core. Background tasks offload work to the background, outside of the normal… - [How To Use The New Bulk Update Feature In EF Core 7](https://milanjovanovic.tech/blog/how-to-use-the-new-bulk-update-feature-in-ef-core-7) (2022-11-26): In this week's newsletter, we're going to explore the new ExecuteUpdate and ExecuteDelete methods that were released with EF7. - [How To Use The Options Pattern In ASP.NET Core 7](https://milanjovanovic.tech/blog/how-to-use-the-options-pattern-in-asp-net-core-7) (2022-11-19): In this week's newsletter I want to show you how you can use the powerful Options pattern in ASP.NET Core 7. - [What's New In .NET 7?](https://milanjovanovic.tech/blog/whats-new-in-dotnet-7) (2022-11-12): In this week's newsletter I want to highlight a few interesting things that are now available with the release of C# 11 and .NET 7. - [5 Ways To Check For Duplicates In Collections, With Benchmarks](https://milanjovanovic.tech/blog/5-ways-to-check-for-duplicates-in-collections) (2022-11-05): In this week's newsletter, we will take a look at five different ways to check if a collection contains duplicates. - [How To Use Global Query Filters in EF Core](https://milanjovanovic.tech/blog/how-to-use-global-query-filters-in-ef-core) (2022-10-29): In this week's newsletter, I'll show you how to remove repetitive conditions from your EF Core queries, like the soft-delete check or the tenantId filter you… - [Introduction To Locking And Concurrency Control in .NET 6](https://milanjovanovic.tech/blog/introduction-to-locking-and-concurrency-control-in-dotnet-6) (2022-10-22): In this week's newsletter, we'll see how we can work with locking in .NET 6. We won't cover how the lock is implemented at the operating system level, only the… - [How I Optimized an API Endpoint to Make It 15x Faster](https://milanjovanovic.tech/blog/how-i-optimized-an-api-endpoint-to-make-it-15x-faster) (2022-10-15): Performance optimizations are my favorite thing about software engineering. Over the last 5 years, I've encountered various performance problems that taught me… - [Decorator Pattern In ASP.NET Core](https://milanjovanovic.tech/blog/decorator-pattern-in-asp-net-core) (2022-10-08): Let's imagine we have an existing Repository implementation, and we want to introduce caching without changing the original class. - [3 Ways To Create Middleware In ASP.NET Core](https://milanjovanovic.tech/blog/3-ways-to-create-middleware-in-asp-net-core) (2022-10-01): Middleware allows us to introduce additional logic before or after executing an HTTP request. - [How To Approach Clean Architecture Folder Structure](https://milanjovanovic.tech/blog/clean-architecture-folder-structure) (2022-09-24): Clean Architecture is a popular approach to structuring your .NET application. It's a layered architecture and splits into four layers: Domain, Application… - [How To Improve Performance With EF Core Query Splitting](https://milanjovanovic.tech/blog/how-to-improve-performance-with-ef-core-query-splitting) (2022-09-17): I recently ran into an issue with Entity Framework Core. The query I was running was constantly timing out. - [Records, Anonymous Types, and Non-Destructive Mutation](https://milanjovanovic.tech/blog/records-anonymous-types-non-destructive-mutation) (2022-09-10): Today, I'm going to share some fascinating things you can do with records and anonymous types. I will introduce you to the concept of non-destructive mutation. - [Why I Write My LINQ Queries Tall, Not Wide](https://milanjovanovic.tech/blog/why-i-write-tall-linq-queries) (2022-09-03): In this newsletter, I'll show you how you can write tall LINQ queries to improve readability and make your code easier to maintain.