Foundation · The wiring of the Web-Stack
Inversion
A dependency injection (IoC) container for Vala — three lifecycles, field injection, multi-registration and scope-local registrations. It is how an Astrologue web application wires itself together at startup.
- Version
0.2- Licence
- LGPL-3.0-or-later
- Package
usm install inversion- Language
- Vala
Overview
Why it exists
Inversion is a dependency injection (IoC) container for Vala. Applications declare what they need; the container decides what concrete thing fills each need, and when a new instance is made versus shared. Nothing in the stack reaches out and constructs its own collaborators — the wiring lives in one place, and that place is testable.
The Web-Stack is built around it. Spry's users and permissions, Invercargill-Sql's connections and sessions, an application's own services — all are registered in a container, resolved in scopes, and injected by field. The companion library Invercargill-Sql-Inversion exists purely to make this container and the database layer one motion.
Features
What it hands you
- Three lifecycles. Transient — a new instance each time; Scoped — one per scope; Singleton — one per container.
- Field injection. Dependencies resolve via
inject<T>()in field initializers; no constructor plumbing. - Multi-registration. Register several implementations for one service type and resolve them all at once.
- Scope-local registrations. Add registrations that only exist within a scope.
- Fluent API. Chained registration methods keep configuration readable.
- Registration metadata. Registrations carry typed metadata that other services can query — how the type provider of the data layer finds its mappers.
Installation
Getting the library
usm install inversion
invercargill-1 itself.From source:
git clone <the Inversion repository>
cd Inversion
meson setup build
ninja -C build
ninja -C build install
valac --pkg inversion-0.1 my-program.vala
.deps chain automatically.Usage & documentation
Quick start, from the README
Define a service, register an implementation, resolve it through a scope:
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<ConsoleLogger>((scope) => new ConsoleLogger())
.as_type(typeof(Logger));
var scope = container.create_scope();
var logger = scope.resolve<Logger>();
logger.log("Hello!");
Lifecycles
One registration per lifetime policy:
container.register_transient<MyService>((s) => new MyService());
container.register_scoped<MyService>((s) => new MyService());
container.register_singleton<MyService>((s) => new MyService());
Field injection
Dependencies are injected using the inject<T>() function in field initializers — resolved automatically when the owning class is created:
public class UserService : Object {
private Logger logger = inject<Logger>();
public void greet(string name) {
this.logger.log(@"Hello, $name!");
}
}
var userService = scope.resolve<UserService>();
inject_all<T>() brings in every implementation: private Lot<Logger> loggers = inject_all<Logger>();Multiple implementations
container.register_singleton<FileLogger>((s) => new FileLogger())
.as_type(typeof(Logger));
container.register_singleton<ConsoleLogger>((s) => new ConsoleLogger())
.as_type(typeof(Logger));
// Get all implementations
var allLoggers = scope.resolve_all<Logger>();
Scopes with their own registrations
var scope = container.create_scope();
// Add a registration only available in this scope
scope.register_singleton<RequestContext>((s) => new RequestContext())
.as_type(typeof(Context));
The repository's examples/ directory walks each feature end to end — BasicUsage.vala, LifecycleDemo.vala, InjectionDemo.vala, MultiRegistration.vala and ScopeRegistrationDemo.vala — and the library's test suite runs through meson test and USM's test exec.
Package & source
The ledger
- Version
0.2(fromMANIFEST.usm)- Licence
- LGPL-3.0-or-later — free to run, study, share and improve; the LGPL keeps it free to link from any program.
- Package
usm install inversion- Provides
libinversion-0.1.so,inversion-0.1.h,inversion-0.1.vapi+.deps,inversion-0.1.gir,inversion-0.1.typelib,inversion-0.1.pc- Needs at runtime
- GLib, GObject, and
libinvercargill-1.so. - Source
- The repository
Tilo15/Inversionon the Astrologue forge (git over ssh, port 222). Free software: the licence guarantees your right to the source.