.NET platform and application architecture concepts explained in depth, one at a time.
Projects, internal visibility, and a contracts assembly per module as a boundary the .NET compiler enforces, with one schema and one DbContext per module.
Synchronous queries through contracts, outbox-backed integration events for reliable delivery, and architecture tests that turn dependency rules into a failing build.
Host one module with a real database, replace the other modules with fakes of their contracts, test outbox events without sleeping, and keep a few full-application tests for the seams.
Records as value objects, strongly-typed IDs, an aggregate root that guards invariants, and encapsulated collections, with the cost of each choice.
Owned types vs complex types, value converters, private constructors and backing fields, and when a repository is worth wrapping around the DbContext.
Events raised by the aggregate and dispatched from a SaveChanges interceptor, domain vs integration events, and the one-aggregate-per-transaction rule.
One context per unit of work, pooling and IDbContextFactory, the entity states in the change tracker, and when AsNoTracking pays off.
The implicit transaction in SaveChanges, concurrency tokens (rowversion and xmin), DbUpdateConcurrencyException, and a retry strategy combined with a manual transaction.
Include and ThenInclude, cartesian explosion and AsSplitQuery, N+1 through lazy loading, projections, and reading the generated SQL with ToQueryString.
Where LINQ to SQL translation stops, compiled queries, ExecuteUpdate and ExecuteDelete, FromSql vs FromSqlRaw, and keyset pagination.
The model snapshot, reviewing generated SQL (a rename that becomes drop and add), data changes in migrationBuilder.Sql, and snapshot conflicts between branches.
The risks of Migrate() at startup with several replicas, idempotent scripts, migration bundles, expand and contract, and concurrent index builds in PostgreSQL.
IHostedService vs BackgroundService, unhandled exceptions that stop the host, scoped services through IServiceScopeFactory, PeriodicTimer, and graceful shutdown.
Bounded Channel<T>, BoundedChannelFullMode, an endpoint as producer and a BackgroundService as consumer, and what a restart loses.
Persistent job storage, retries, idempotency under at-least-once delivery, recurring jobs, and passing IDs instead of entities.
The compiler state machine, SynchronizationContext and ConfigureAwait, deadlocks with .Result, async void, and the rules of ValueTask.
Cancellation and timeouts, throttling with SemaphoreSlim, fan-out and fan-in with Channels, TaskCompletionSource, and ConcurrentDictionary.GetOrAdd pitfalls.
CPU-bound vs I/O-bound work, Parallel.ForEachAsync, PLINQ, localInit and localFinally, and when parallel code gets slower.