Across one consumer integration, four separate failure modes all came down to "module X is in the assembly graph but its peer module is missing":
| Missing peer |
Symptom |
| Admin needs OpenIddict |
Startup crash, Body was inferred… (misleading minimal-API error) |
| Email needs BackgroundJobs |
Startup crash, Unable to resolve IBackgroundJobs |
| Admin/Users/etc. need Localization |
Silent — every label renders as bare key (Users.Title, Roles.ColName) |
| Tenants needs FeatureFlags |
Same *.Contracts-only ProjectReference shape |
The crash cases are partially addressed by declaring runtime deps as PackageReferences (separate issue). But the silent-fallback cases (Localization missing → bare keys; menu items pointing to nonexistent peer routes) need an actual diagnostic.
Suggested fix
A single boot-time pass that:
- Scans
[Module]-attributed types for declared dependencies
- Inspects endpoint handlers' DI parameter requirements
- Inspects shared
useTranslation() calls vs TranslationLoader registration
- Emits clear diagnostics:
ModuleX endpoint Y requires service Z which is not registered (install module Q)
ModuleX uses translations but SimpleModule.Localization is not installed; UI labels will render as bare keys
Could ship as builder.AddSimpleModule(o => o.ValidateModuleGraph = true) for opt-in until stable.
Across one consumer integration, four separate failure modes all came down to "module X is in the assembly graph but its peer module is missing":
Body was inferred…(misleading minimal-API error)Unable to resolve IBackgroundJobsUsers.Title,Roles.ColName)*.Contracts-only ProjectReference shapeThe crash cases are partially addressed by declaring runtime deps as PackageReferences (separate issue). But the silent-fallback cases (Localization missing → bare keys; menu items pointing to nonexistent peer routes) need an actual diagnostic.
Suggested fix
A single boot-time pass that:
[Module]-attributed types for declared dependenciesuseTranslation()calls vsTranslationLoaderregistrationModuleX endpoint Y requires service Z which is not registered (install module Q)ModuleX uses translations but SimpleModule.Localization is not installed; UI labels will render as bare keysCould ship as
builder.AddSimpleModule(o => o.ValidateModuleGraph = true)for opt-in until stable.