FactoryContainer constructor

FactoryContainer({
  1. List<FactoryModule> modules = const [],
  2. FactoryContainer? parent,
  3. List<Factory<Object>> local = const [],
  4. List<FactoryOverride> overrides = const [],
  5. FactoryObserver? observe,
})

Installs declarations locally and inherits unmodified values from parent.

Implementation

FactoryContainer(
    {List<FactoryModule> modules = const [],
    this.parent,
    List<Factory<Object>> local = const [],
    List<FactoryOverride> overrides = const [],
    FactoryObserver? observe})
    : _observe = observe ?? parent?._observe {
  parent?._checkOpen();
  for (final module in modules) {
    _factories.addAll(module.factories);
    for (final factory in module.expose) {
      if (!module.factories.contains(factory)) {
        throw ArgumentError(
            'Exposed $factory is not installed in its module.');
      }
      final previous = _exposed[factory.valueType];
      if (previous != null && !identical(previous, factory)) {
        throw ArgumentError(
            'Duplicate exposed type ${factory.valueType}: $previous and '
            '$factory conflict in the same Factory scope. Expose only one.');
      }
      _exposed[factory.valueType] = factory;
    }
  }
  _factories.addAll(local);
  for (final override in overrides) {
    if (_overrides.containsKey(override.factory)) {
      throw ArgumentError('Duplicate override for ${override.factory}.');
    }
    _factories.add(override.factory);
    _overrides[override.factory] = override;
  }
  parent?._children.add(this);
  try {
    for (final factory in _factories) {
      if (!factory.lazy) read(factory);
    }
  } catch (error, stack) {
    // A synchronous opening failure still exposes the asynchronous cleanup.
    final cleanup = close();
    unawaited(cleanup.catchError((Object _) {}));
    throw FactoryInitializationException(error, stack, cleanup);
  }
}