Startup flow
Purpose
Describe ordering guarantees during cold start: what runs before ServiceProvider exists, what runs after, and where modules plug in.
Code location
Mnemo.UI/App.axaml.cs— Avalonia lifetime; createsMainWindow.Mnemo.UI/Services/Bootstrapper.cs— DI composition, module discovery, post-build registration.
Main interfaces / classes
Bootstrapper.Build— static factory returning rootIServiceProvider.App— assignsServices, applies theme continuation, shows main window synchronously (noTask.Runaround shell creation).
Lifecycle (numbered)
Roughly:
- App starts (
App.OnFrameworkInitializationCompleted). Bootstrapper.Build()createsServiceCollection.- Infrastructure + shared UI services register (storage, AI stack, navigation hosts, registries, …).
DiscoverModules()scans loadedMnemo.*assemblies for concreteIModuletypes and instantiates them (Activator.CreateInstance).- Translation sources aggregate →
LocalizationServiceregisters. - Each module
ConfigureServicesruns viaServiceRegistrarwrapping the sameIServiceCollection. - Keybind manifests aggregate →
KeyMapServicebuilds after repositories register. BuildServiceProvider().- Each module
RegisterRoutes,RegisterSidebarItems,RegisterTools,RegisterWidgetswith liveIServiceProvider. MainWindowshown;MainWindowViewModelresolves from DI.
How to extend
- Hook feature work in
IModulemethods—avoid ad hoc registration scattered outside bootstrap unless it is truly cross-cutting. - Background seed tasks (e.g. welcome content) follow patterns inside
Bootstrapper—do not block UI thread on DB.
Gotchas
- Module discovery silently skips types that throw on construction—misconfigured parameterless constructors vanish without logs until you add diagnostics.
- Ordering:
RegisterTranslationSourcesruns before provider build; tools/widgets run after, so they may resolve real services.
Related: Dependency injection, Module system