# Inversion IoC Container ## Overview Inversion is a dependency injection (IoC) container for Vala that provides inversion of control through component registration, lifecycle management, and field injection. It supports transient, scoped, and singleton lifecycles with a fluent registration API. ## Core Components ### Container The central registry for component registrations. Holds singleton instances and creates scopes for scoped resolution. ### Scope Manages scoped instance lifetime. Created from a container and maintains its own cache of scoped instances. ### Registration Represents a component registration with implementation type, service aliases, lifecycle, and factory. ### Lifecycle Enum defining instance lifetime: `TRANSIENT`, `SCOPED`, `SINGLETON`. ### Factory Interface for creating instances. Implementations: `DelegateFactory`, `InstanceFactory`. ## Dependencies - GLib 2.0 - GObject 2.0 - Invercargill-1 ## Quick Start ```vala using Inversion; // Define service interface and implementation 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); } } // Create container and register var container = new Container(); container.register_singleton((scope) => new ConsoleLogger()) .as_type(typeof(Logger)); // Resolve via scope var scope = container.create_scope(); var logger = scope.resolve(); logger.log("Hello!"); ``` ## Registration Patterns ### Basic Registration ```vala // Register with factory delegate container.register_singleton((scope) => new MyService()); // Register as interface container.register_singleton((scope) => new MyImplementation()) .as_type(typeof(IMyService)); ``` ### Multiple Interfaces ```vala container.register((scope) => new MyImplementation()) .as_type(typeof(IServiceA)) .as_type(typeof(IServiceB)) .with_lifecycle(Lifecycle.SCOPED); ``` ### Multiple Implementations ```vala container.register_singleton((s) => new FileLogger()) .as_type(typeof(Logger)); container.register_singleton((s) => new ConsoleLogger()) .as_type(typeof(Logger)); // Resolve all implementations var all_loggers = scope.resolve_all(); ``` ## Field Injection Dependencies can be injected via field initializers using `inject()`: ```vala public class UserService : Object { private Logger logger = inject(); private Lot handlers = inject_all(); public void greet(string name) { this.logger.log(@"Hello, $name!"); } } ``` The injection context is automatically established during container resolution. Field initializers execute within the active scope, allowing dependencies to be resolved. ## Error Handling ### ContainerError - `NOT_REGISTERED`: Requested type not registered - `CYCLE_DETECTED`: Circular dependency found - `ILLEGAL_LIFECYCLE_COMBINATION`: Invalid lifecycle for scope context ```vala try { var service = scope.resolve(); } catch (ContainerError.NOT_REGISTERED e) { // Handle missing registration } catch (ContainerError.CYCLE_DETECTED e) { // Handle circular dependency } catch (Error e) { // Handle other errors } ``` --- Inversion is a Vala IoC container providing dependency injection through component registration with transient, scoped, and singleton lifecycles, field injection via `inject()`, multi-registration support, and scope-local registrations.