Skip to content

Skirnir

Skirnir provides an IoC (Inversion of Control) Container for dependency injection in C++. Skirnir uses C++26 compile-time reflection (std::meta::info, the splice operator [: ... :], and ^^T) to automatically extract constructor parameters and enable seamless dependency injection.

Features

  • Automatic Dependency Injection: Automatically resolves constructor dependencies
  • Multiple Lifetimes: Support for Singleton, Scoped, and Transient lifetimes
  • Multi-Registration: Register and resolve multiple implementations of a contract with GetServices<T>() or std::vector<Arc<T>> injection
  • Keyed / Named Services: Distinguish multiple implementations of one contract by string key — resolve via GetKeyedService<T>(key) or Keyed<T, "key"> ctor injection
  • Optional Dependencies: std::optional<Arc<T>> ctor parameters resolve to nullopt when T is not registered
  • Late Registration: ServiceProvider::Add* / Remove after build for plugin attach/detach — see Late Registration
  • Non-throwing Resolution: TryGetService<T>() and TryGetKeyedService<T>(key) return std::optional<Arc<T>> instead of throwing
  • Captive-Dependency Detection: ValidateOnBuild() flags Singletons that transitively depend on Scoped services
  • Configuration: Strongly-typed JSON configuration with Bind<T>(), typed getters, sub-sections, and source chaining
  • Diagnostics: ValidateOnBuild() and PrintDiagnostics(std::ostream&) for early failure detection
  • Circular Dependency Detection: Detects and reports circular dependencies
  • Logging: Built-in logging with pluggable sinks (ConsoleSink, FileSink, JsonSink, AsyncSink) and scopes/correlation IDs
  • Reflection: Uses C++26 compile-time reflection (std::meta::info, splice operator [: ... :]) to extract service metadata
  • Applications: Structured application model with IApplication and ApplicationBuilder
  • Extensions: Modular service registration via composable extensions (includes a ready-made LoggingExtension)

Quick Start

#include <Skirnir/Skirnir.hpp>

int main() {
    auto serviceCollection = skr::ServiceCollection();

    serviceCollection.AddSingleton<MySingleton>();
    serviceCollection.AddScoped<MyScoped>();
    serviceCollection.AddTransient<MyTransient>();

    auto serviceProvider = serviceCollection.CreateServiceProvider();
    auto myService = serviceProvider->GetService<MySingleton>();

    return 0;
}

Installation

Skirnir uses CMake for building. Add the following to your CMakeLists.txt:

add_subdirectory(Skirnir)
target_link_libraries(your_target PRIVATE Skirnir)

License

MIT License