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 null if 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 parent container.

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 T is 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, returning null if 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 value for type T.
removeOverride<T>([Type? type]) → void
Removes a test override registered for generic type T or explicit type.
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