# Container Class ## Overview `Container` is the inversion of control container that manages component registrations and lifecycles. It stores registrations, manages singleton instances, creates scopes, and provides dependency resolution. ## Namespace `Inversion` ## Class Declaration ```vala public class Container : Object ``` ## Constructor ### `Container()` Creates a new container with empty registrations. The container automatically registers itself as a singleton. ```vala var container = new Container(); ``` ## Registration Methods ### `register(owned FactoryDelegate factory_func, Lifecycle lifecycle)` Registers a type with a factory delegate and specified lifecycle. Returns a `Registration` for fluent configuration. ```vala container.register((scope) => new MyService(), Lifecycle.SINGLETON); ``` ### `register_transient(owned FactoryDelegate factory_func)` Registers a type as transient (new instance per resolve). ```vala container.register_transient((scope) => new MyService()); ``` ### `register_scoped(owned FactoryDelegate factory_func)` Registers a type as scoped (one instance per scope). ```vala container.register_scoped((scope) => new MyService()); ``` ### `register_singleton(owned FactoryDelegate factory_func)` Registers a type as singleton (one instance per container). ```vala container.register_singleton((scope) => new MyService()); ``` ### `register_startup(owned FactoryDelegate factory_func)` Registers a type as startup (eagerly initialized singleton). Instance is created when `initialise()` is called. ```vala container.register_startup((scope) => new DatabaseConnection()); ``` ### `register_type(Type implementation_type, owned FactoryDelegate factory_func, Lifecycle lifecycle)` Non-generic version for runtime type registration. ```vala container.register_type(typeof(MyService), (scope) => new MyService(), Lifecycle.TRANSIENT); ``` ### `register_factory_type(Type implementation_type, Factory factory, Lifecycle lifecycle)` Registers with a custom `Factory` instance. ```vala var factory = new MyCustomFactory(); container.register_factory_type(typeof(MyService), factory, Lifecycle.SINGLETON); ``` ### `register_factory(Factory factory, Lifecycle lifecycle)` Generic version of factory registration. ```vala container.register_factory(custom_factory, Lifecycle.SCOPED); ``` ## Initialization Methods ### `initialise() throws Error` Eagerly instantiates all components registered with `Lifecycle.STARTUP`. Call this after all registrations are complete to ensure startup components are ready before the application runs. ```vala container.register_startup((s) => new DatabaseConnection()); container.register_startup((s) => new CacheService()); // Initialize all startup components try { container.initialise(); } catch (Error e) { // Handle initialization failure (e.g., database connection failed) error("Failed to initialize: %s", e.message); } ``` ## Query Methods ### `is_registered(Type type) → bool` Checks if a type has any registrations. ```vala if (container.is_registered(typeof(Logger))) { // Type is registered } ``` ### `get_registration(Type service_type) throws ContainerError → Registration` Gets any registration for a type. Throws `ContainerError.NOT_REGISTERED` if not found. ```vala try { var reg = container.get_registration(typeof(IMyService)); } catch (ContainerError.NOT_REGISTERED e) { // Not registered } ``` ### `get_registrations(Type service_type) → Enumerable` Gets all registrations for a type (may be empty). ```vala var regs = container.get_registrations(typeof(Logger)); // Iterate over all Logger registrations ``` ## Scope Creation ### `create_scope() → Scope` Creates a new scope for scoped instance resolution. ```vala var scope = container.create_scope(); var service = scope.resolve(); ``` ### `create_transient_scope() → Scope` Creates a scope with transient lifecycle semantics. ```vala var scope = container.create_transient_scope(); ``` ## Internal Methods ### `get_or_create_singleton(Registration registration, Type requested_type) throws Error → Object` Gets existing singleton or creates new instance. Used internally by `Scope` during resolution. ## Usage Example ```vala var container = new Container(); // Register implementations container.register_singleton((scope) => new ConsoleLogger()) .as_type(typeof(ILogger)); container.register_scoped((scope) => new UserService()) .as_type(typeof(IUserService)); container.register_transient((scope) => new RequestHandler()); // Register startup components container.register_startup((scope) => new DatabaseConnection()); // Initialize startup components container.initialise(); // Create scope and resolve var scope = container.create_scope(); var logger = scope.resolve(); var users = scope.resolve_all(); ``` ## Multi-Registration Multiple implementations can be registered for the same service type: ```vala container.register_singleton((s) => new FileLogger()) .as_type(typeof(ILogger)); container.register_singleton((s) => new ConsoleLogger()) .as_type(typeof(ILogger)); // Resolve all implementations var scope = container.create_scope(); var all_loggers = scope.resolve_all(); ``` --- The Container class is the central registry for Inversion IoC, providing registration methods for transient, scoped, singleton, and startup lifecycles, scope creation, and singleton instance management.