Factories create component instances in Inversion. The Factory interface defines the contract, with DelegateFactory and InstanceFactory as built-in implementations. Custom factories can implement complex instantiation logic.
Inversion
public interface Factory : Object
create(Scope scope) throws Error → ObjectCreates a new instance of the component. The scope parameter enables dependency resolution during creation.
public interface Factory : Object {
public abstract Object create(Scope scope) throws Error;
}
DelegateFactory wraps a FactoryDelegate function for instance creation. This is the most commonly used factory, created automatically by container registration methods.
public class DelegateFactory : Object, Factory
public DelegateFactory(owned FactoryDelegate delegate)
// Container methods create DelegateFactory internally
container.register_singleton<MyService>((scope) => new MyService());
// Equivalent manual creation
var factory = new DelegateFactory((scope) => new MyService());
container.register_factory<MyService>(factory, Lifecycle.SINGLETON);
container.register_scoped<OrderService>((scope) => {
var repo = scope.resolve<IOrderRepository>();
var logger = scope.resolve<ILogger>();
return new OrderService(repo, logger);
});
InstanceFactory always returns a pre-existing instance. Used for scope-local instance caching and registering already-created objects.
public class InstanceFactory : Object, Factory
| Property | Type | Description |
|---|---|---|
registration |
Registration |
Associated registration |
public InstanceFactory(Registration registration, Object instance)
// Register an existing instance
var existing_service = new MyConfiguredService();
var registration = new Registration(typeof(MyConfiguredService),
new InstanceFactory(reg, existing_service),
Lifecycle.SINGLETON);
public delegate Object FactoryDelegate(Scope scope) throws Error;
The delegate signature used by DelegateFactory. Receives the current scope for resolving dependencies.
scope: The active scope for dependency resolutionFactoryDelegate factory = (scope) => {
var dependency = scope.resolve<IDependency>();
return new MyService(dependency);
};
public class PoolFactory : Object, Factory {
private Type element_type;
private Queue<Object> pool = new Queue<Object>();
public PoolFactory(Type element_type) {
this.element_type = element_type;
}
public Object create(Scope scope) throws Error {
Object? pooled = pool.try_pop();
if (pooled != null) {
return pooled;
}
return Object.new(element_type);
}
public void return_to_pool(Object instance) {
pool.push(instance);
}
}
// Usage
var pool_factory = new PoolFactory(typeof(PooledObject));
container.register_factory_type(typeof(PooledObject), pool_factory, Lifecycle.TRANSIENT);
public class LazyFactory : Object, Factory {
private Factory inner_factory;
private Object? cached_instance;
private Mutex mutex = Mutex();
public LazyFactory(Factory inner) {
this.inner_factory = inner;
}
public Object create(Scope scope) throws Error {
mutex.lock();
if (cached_instance == null) {
cached_instance = inner_factory.create(scope);
}
mutex.unlock();
return cached_instance;
}
}
| Lifecycle | Factory Usage |
|---|---|
| TRANSIENT | Factory called on every resolve |
| SCOPED | Factory called once per scope, then cached |
| SINGLETON | Factory called once per container, then cached |
Factories are associated with registrations:
// DelegateFactory created internally
var reg = container.register_transient<MyService>((s) => new MyService());
// Access factory if needed
var factory = reg.factory;
Inversion provides Factory interface with DelegateFactory for delegate-based creation and InstanceFactory for existing instances, supporting custom implementations for complex instantiation scenarios.