Dependency injection
Purpose
Centralize construction of long-lived services and keep ViewModels testable by depending on interfaces from Core.
Code location
- Registration:
Mnemo.UI/Services/Bootstrapper.cs - Core abstraction:
Mnemo.Core/Services/IServiceRegistrar.cs - Adapter:
Mnemo.UI/Services/ServiceRegistrar.cs→ forwards toMicrosoft.Extensions.DependencyInjection.IServiceCollection
Main interfaces / classes
| Type | Role |
|---|---|
IServiceRegistrar | Module-facing minimal API (AddSingleton, AddTransient) without exposing full MS DI surface to Core consumers unnecessarily |
ServiceRegistrar | Bridges IServiceRegistrar calls to ServiceCollection |
IServiceProvider | Resolved root from services.BuildServiceProvider() |
Startup / registration flow
- Bootstrapper registers Infrastructure singletons and UI shell services directly on
ServiceCollection. ServiceRegistrarwraps the same collection forIModule.ConfigureServices.- Provider built once; modules then receive
IServiceProviderforRegisterTools/RegisterWidgets.
How to extend
- Cross-cutting singleton: add in
Bootstrappernear related peers (logging, storage, AI). - Feature-scoped VM or service: register inside the feature
IModule.ConfigureServiceswith transient vs singleton deliberately (VMs often transient).
Gotchas
- Modules instantiate via
Activator.CreateInstance— parameterless constructors required for module classes themselves. - Capturing
IServiceProviderin long-lived objects—prefer typed dependencies; service locator spread makes testing harder.
Related: Module system