Skip to main content

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 to Microsoft.Extensions.DependencyInjection.IServiceCollection

Main interfaces / classes

TypeRole
IServiceRegistrarModule-facing minimal API (AddSingleton, AddTransient) without exposing full MS DI surface to Core consumers unnecessarily
ServiceRegistrarBridges IServiceRegistrar calls to ServiceCollection
IServiceProviderResolved root from services.BuildServiceProvider()

Startup / registration flow

  1. Bootstrapper registers Infrastructure singletons and UI shell services directly on ServiceCollection.
  2. ServiceRegistrar wraps the same collection for IModule.ConfigureServices.
  3. Provider built once; modules then receive IServiceProvider for RegisterTools / RegisterWidgets.

How to extend

  • Cross-cutting singleton: add in Bootstrapper near related peers (logging, storage, AI).
  • Feature-scoped VM or service: register inside the feature IModule.ConfigureServices with transient vs singleton deliberately (VMs often transient).

Gotchas

  • Modules instantiate via Activator.CreateInstanceparameterless constructors required for module classes themselves.
  • Capturing IServiceProvider in long-lived objects—prefer typed dependencies; service locator spread makes testing harder.

Related: Module system