Where this course actually stands

This course is further out than you would like

A waitlist page with a "coming soon" badge sets a clock running in your head. Mine has been wrong for a while, so I took the badge down and wrote what is actually true instead.

Done

The curriculum

Fifteen chapters and thirty-eight lessons, outlined end to end. The sample domain, the two procedural handlers we refactor, and the order the patterns appear in are all settled. That is the curriculum you can read further down this page.

Not done

The course itself

An outline is not a course. The lessons still have to be built, recorded, and edited, and the sample codebase has to be good enough that you can drop into any chapter and follow along. Until that exists, there is nothing here worth your money.

Unknown

The launch date

I would rather say nothing than give you a date I end up missing. My honest read today is months away, not weeks. If that changes in either direction, the waitlist hears it first.

What to do in the meantime

Don't wait on this page. If you want to start modeling domains properly now, Pragmatic Clean Architecture already covers the tactical DDD patterns (entities, value objects, domain events) inside a full architecture, and it exists today. I also write about domain modeling most weeks on the blog, for free.

What's inside

Earn the patterns instead of applying them

Every chapter follows the same rhythm. Notice the friction, reshape the code, and watch a DDD building block fall out of the refactoring.

.NET 10

ASP.NET Core Web API

EF Core

Mapping a rich model without fighting it

PostgreSQL

Production-grade persistence

xUnit + Testcontainers

Real unit and integration tests

A refactor-first path, not a pattern catalog

The course does not open with a list of DDD patterns to memorize. It opens with a procedural codebase, finds where that code resists change, and refactors until a pattern is the obvious answer.

Two real "monster" handlers

Two procedural handlers thread through the whole course. The friction in them is systemic rather than cosmetic, and the same refactoring moves work on both.

Complexity past the Customer-with-an-Address demo

The Learnify domain has course capacity, tiered revenue share, refund cascades that span aggregates, and bounded contexts across Catalog, Learning, Billing, and Identity. Close enough to real work to transfer to it.

A tagged git ref for every chapter

Each chapter is planned to have a clear starting and ending commit, so you can drop in anywhere. Skip ahead, jump back, or follow the whole arc.

What you will be able to do afterwards

  • Establish a Ubiquitous Language between code and the business
  • Read code for friction signals to drive refactoring decisions
  • Push behavior into entities by listening to where it wants to live
  • Encapsulate data with private setters, factories, and value objects
  • Encapsulate collections with backing fields and read-only access
  • Unit test domain entities and value objects with no infrastructure
  • Use domain events to decouple cascading side effects
  • Draw aggregate boundaries that protect transactional invariants
  • Identify bounded contexts with concrete teeth
  • Know when to apply all of this, and when to leave code simple

The planned curriculum

15 chapters. 38 lessons.

Five phases (Foundations, Story, Domain Model, Hardening, and Strategic View) take a procedural codebase to a rich domain model with bounded contexts.

This is the outline, not a recorded course. The runtimes below are targets I wrote while planning, and both they and the chapter order can still change before launch.
01IntroductionWelcome
  • Welcome and what you’ll build
  • Audience and setup
02Why Rich Domain ModelsConcept
  • The Anemic Domain Model anti-pattern
  • Why prescriptive DDD doesn’t work
  • Friction signals as our guide
03The Ubiquitous LanguageConcept
  • Why language matters more than patterns
  • Discovering Learnify’s language
04The Starting CodebaseWalkthrough
  • Project structure walkthrough
  • The two monster handlers and the friction inventory
05Making the Handler Tell a StoryPractical
  • When a handler does too much
  • Stepping the handler down a level of abstraction (demo)
  • Isolating the external integration as a Domain Service
06Pushing Behavior into the DomainPractical
  • Why our handler is still procedural
  • Undo, reshape, relocate
  • Behavior on the entity
07Sealing Entity StatePractical
  • Why public setters defeat domain methods
  • Private setters and the factory
  • EF Core compatibility and exercise
08Eliminating Primitives with Value ObjectsPractical
  • The value-object concept
  • Money (with currency invariants) and Email
  • Tiered revenue share and EF Core
09Protecting CollectionsPractical
  • Why exposed collections leak
  • Encapsulating collections
10Testing the Domain ModelPractical
  • The testing pyramid for a rich domain
  • Unit tests on entities and value objects
  • Integration tests at the handler boundary
11Decoupling Side Effects with Domain EventsPractical
  • The event concept
  • Define, raise, dispatch
  • Move side effects (the refund cascade)
12Making Implicit Concepts ExplicitPractical
  • Smart enumerations for CourseStatus
  • Policies: RefundPolicy and tiered RevenueSharePolicy
13Aggregate DesignPractical
  • What is an aggregate? (with capacity as the real invariant)
  • Diagnose the current Course aggregate
  • Extract Enrollment and reference by id
14Strategic Design & Bounded ContextsConcept
  • The “one model” trap
  • Bounded contexts and the context map
  • Mapping patterns and modular monolith vs microservices
15Wrap-Up & Next StepsRecap
  • Before & after
  • Where next, and closing thoughts
Tell me when it launches
Course student
Course student
Course student
Course student
Course student
Course student

9,700+ engineers are already learning from my other courses

Milan Jovanović

Who's behind this

Hi, I'm Milan Jovanović. I help engineers level up their .NET and software architecture skills.

I'm a Software Architect and Microsoft MVP for Developer Technologies with years of experience building large-scale systems with rich domain models.

I've helped thousands of engineers improve through my practical tips on social media, The .NET Weekly newsletter, and my YouTube channel.

My goal with this course is to teach you to read code for friction signals and refactor toward a domain model that earns its complexity, without ceremony or dogma. That is worth doing properly, which is the main reason it isn't out yet.

Microsoft MVP Badge

Got questions?

Frequently asked questions

  • When does the course launch?

    I don't know, and I'm not going to invent a date. My honest read today is that it is months away rather than weeks.

    This page carried a "coming soon" badge for far longer than it deserved. Taking it down felt better than letting it keep implying a launch that isn't close.

  • Can I pre-order or pay to reserve a spot?

    No. There is nothing to buy on this page and there won't be until the course exists. No pre-orders, no deposits, no founding-member tiers. Joining the waitlist costs you an email address and nothing else.

  • Then what is the waitlist actually for?

    One email when the course launches, plus the launch discount for people on the list. I won't use it to drip fake progress updates at you in the meantime.

  • Will the curriculum change before then?

    Probably, at least a little. What you see below is a detailed outline, and outlines shift once the lessons get built. The five-phase arc and the refactor-first approach are settled. Individual lesson titles, ordering, and runtimes are not.

  • What should I do while I wait?

    Don't put your learning on hold for a course that doesn't exist yet. Pragmatic Clean Architecture already covers the tactical DDD patterns inside a complete architecture, and everything on the blog is free.

  • Who is this course for?

    Intermediate .NET developers who are comfortable with C# and Entity Framework, but new to Domain-Driven Design. Or who've tried DDD and ended up with anemic models anyway.

    If you write production .NET applications and want to push real behavior into your domain model, this course is for you. No prior DDD knowledge is required.

  • What will I learn?

    How to refactor a procedural codebase into a rich domain model by reading the code, listening to friction signals, and relocating behavior toward where it belongs.

    • The Ubiquitous Language and Bounded Contexts
    • Entities with real behavior (and sealed state)
    • Value Objects with real invariants (currency, ranges, money)
    • Domain Events and the refund cascade
    • Aggregate boundaries and capacity invariants
    • Testing rich domain models

    All examples target .NET 10.

  • How is this different from other DDD courses?

    Most DDD content prescribes patterns up front. This course does the opposite. It starts with a real, ugly procedural codebase and lets the building blocks (Entity, Value Object, Domain Service, Aggregate, Bounded Context) emerge as we refactor, so every pattern you end up using is one you earned rather than one you copied.

  • What tech stack is used?

    • .NET 10 / ASP.NET Core Web API
    • Entity Framework Core with PostgreSQL (via Docker)
    • Custom CQRS abstractions
    • xUnit with Testcontainers for unit and integration tests
  • Got more questions?

    Reach out via the contact page and I'll get back to you.

Still interested?

Join the waitlist and forget about it

That is genuinely the best way to handle this one. I'll email you when Pragmatic Domain-Driven Design is finished and worth buying. It may be a long wait, and you won't hear from me about it in the meantime.

Course student
Course student
Course student
Course student
Course student
Course student

9,700+ engineers are already learning from my other courses

One email at launch, not a drip campaign
No pre-orders and no deposits
Waitlist gets the launch discount