# Inversion A dependency injection (IoC) container for Vala. ## Features - **3 Lifecycles**: Transient (new instance each time), Scoped (one per scope), Singleton (one per container) - **Field injection**: Dependencies resolved via `inject()` in field initializers - **Multi-registration**: Register multiple implementations for the same service type - **Scope-local registrations**: Add registrations that only exist within a scope - **Fluent API**: Chain methods for readable configuration ## Dependencies - GLib 2.0 - GObject 2.0 - Invercargill-1 ## Building ```bash meson setup builddir meson compile -C builddir ``` ## Quick Start ```vala using Inversion; // Define your service public interface Logger : Object { public abstract void log(string message); } public class ConsoleLogger : Object, Logger { public void log(string message) { stdout.printf("[LOG] %s\n", message); } } // Register and resolve var container = new Container(); container.register_singleton((scope) => new ConsoleLogger()) .as_type(typeof(Logger)); var scope = container.create_scope(); var logger = scope.resolve(); logger.log("Hello!"); ``` ## Lifecycles | Lifecycle | Behavior | |-----------|----------| | `TRANSIENT` | New instance created every resolve | | `SCOPED` | One instance per scope | | `SINGLETON` | One instance per container | ```vala container.register_transient((s) => new MyService()); container.register_scoped((s) => new MyService()); container.register_singleton((s) => new MyService()); ``` ## Multiple Implementations ```vala container.register_singleton((s) => new FileLogger()) .as_type(typeof(Logger)); container.register_singleton((s) => new ConsoleLogger()) .as_type(typeof(Logger)); // Get all implementations var allLoggers = scope.resolve_all(); ``` ## Field Injection Dependencies are injected using the `inject()` function in field initializers: ```vala public class UserService : Object { private Logger logger = inject(); public void greet(string name) { this.logger.log(@"Hello, $name!"); } } // Dependencies are resolved automatically when UserService is created var userService = scope.resolve(); ``` Use `inject_all()` to inject all implementations of a service: ```vala public class MultiLogger : Object { private Lot loggers = inject_all(); } ``` ## Scopes Scopes manage scoped instance lifetime and can have their own local registrations: ```vala var scope = container.create_scope(); // Add a registration only available in this scope scope.register_singleton((s) => new RequestContext()) .as_type(typeof(Context)); ``` ## Examples See the `examples/` directory for more detailed usage: - `BasicUsage.vala` - Registration and resolution basics - `LifecycleDemo.vala` - Transient vs Scoped vs Singleton - `InjectionDemo.vala` - Field injection with `inject()` - `MultiRegistration.vala` - Multiple implementations per service - `ScopeRegistrationDemo.vala` - Scope-local registrations