getOrCreate<T> method

ZenithNode<T> getOrCreate<T>(
  1. ZenithKey<T> key,
  2. T factory(
    1. ZenithRef ref
    )
)

Type-safe node retrieval or creation using a ZenithKey.

If a ZenithOverride was registered for key on this container, its factory is used instead of factory. Nodes created this way live in the same internal storage as getOrCreateNode, so invalidate and invalidateKey both operate on them consistently.

Throws StateError if the container has been disposed.

Implementation

ZenithNode<T> getOrCreate<T>(
  ZenithKey<T> key,
  T Function(ZenithRef ref) factory,
) {
  if (_isDisposed) {
    throw StateError('Cannot create node in disposed ZenithContainer');
  }

  _assertCaptiveDependencyAllowed(key);

  final existing = _nodes[key];
  if (existing != null) {
    return existing as ZenithNode<T>;
  }

  final overrideFactory = _overrides[key] as T Function(ZenithRef ref)?;
  final effectiveFactory = overrideFactory ?? factory;

  final ref = ZenithRef(this);
  _refs[key] = ref;

  final T initialValue;
  try {
    initialValue = effectiveFactory(ref);
  } catch (_) {
    ref._dispose();
    _activeRefs.remove(ref);
    _refs.remove(key);
    rethrow;
  }

  final node = ZenithNode<T>(initialValue);
  _nodes[key] = node;
  return node;
}