BloomContainer class
Lightweight, hierarchical Dependency Injection (DI) container for Bloom JS Native applications.
BloomContainer manages service registrations, lifecycle scopes (transient, singleton, value), hierarchical parent-child inheritance, and test overrides without any reflection or Flutter dependencies.
Lifecycles & Registration Kinds
- Transient (provide): The factory is executed on every inject call, returning a new instance each time.
- Singleton (provideSingleton): The factory is executed once (either immediately or upon first inject
when
lazy: true), and the same instance is returned for all subsequent resolutions in this container. - Value (provideValue): A pre-existing instance is bound directly to the container.
- Test Overrides (override, overrideType): High-priority instances that supersede registered factories without unregistering them, easily reverted via removeOverride.
Hierarchy & Scoping
Containers support hierarchical resolution through parent. When resolving via inject or injectOrNull, the container first checks its local overrides, then its local bindings, and finally delegates to its parent container if not found locally.
Error Handling
- inject throws a StateError if the requested type has not been registered in the container or any ancestor.
- injectOrNull gracefully returns
nullif the requested type is unregistered.
SSR & Browser Compatibility
Safe for both server-side rendering and client-side browser runtimes. On SSR servers, child containers can be created per HTTP request to achieve request-scoped dependency isolation:
final requestContainer = BloomContainer(parent: globalContainer);
requestContainer.provideValue<UserSession>(session);
Example
final container = BloomContainer();
// Register dependencies
container.provideSingleton<BloomHttpClient>(() => BloomHttpClient());
container.provide<AuthService>(() => AuthService(client: container.inject()));
// Resolve
final auth = container.inject<AuthService>();
See also:
- globalContainer, the default ambient container instance.
- inject, the global shortcut for
globalContainer.inject<T>(). - provideSingleton, the global shortcut for
globalContainer.provideSingleton<T>().
Constructors
- BloomContainer({BloomContainer? parent})
-
Creates a BloomContainer with an optional
parentcontainer.
Properties
- hashCode → int
-
The hash code for this object.
no setterinherited
- parent → BloomContainer?
-
Optional parent container for hierarchical dependency lookup fallback.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
dumpContainer(
) → Map< String, dynamic> - Dumps diagnostic metadata about all registered bindings and overrides in this container.
-
has<
T> () → bool -
Checks whether a provider or override for type
Tis registered in this container or its ancestors. -
inject<
T> () → T -
Resolves a dependency of type
T. -
injectOrNull<
T> () → T? -
Resolves a dependency of type
T, returningnullif unregistered. -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
override<
T> (T instance) → void -
Registers a high-precedence test override for generic type
T. -
overrideType(
Type type, dynamic instance) → void -
Registers a high-precedence test override for an explicit runtime
type. -
provide<
T> (FactoryFunc< T> factory) → void -
Registers a transient factory for type
T. -
provideSingleton<
T> (FactoryFunc< T> factory, {bool lazy = true}) → void -
Registers a singleton factory for type
T. -
provideValue<
T> (T value) → void -
Registers an existing instance
valuefor typeT. -
removeOverride<
T> ([Type? type]) → void -
Removes a test override registered for generic type
Tor explicittype. -
reset(
) → void - Clears all local bindings and overrides from this container.
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited