# doGetSingleton method

1. @protected

Future<TypedInstance?> doGetSingleton(

1. String name, {
2. bool allowEarlyReference = true,
3. ObjectFactory<Object>? factory,

})
inherited

Get the singleton instance for the given name.

This method is used to retrieve the singleton instance for the given name.

`name`: The name of the singleton to retrieve `allowEarlyReference`: Whether to allow early references to the singleton `factory`: The factory to use to create the singleton if necessary

Example:

    final userService = registry.doGetSingleton('userService');

## Implementation

    @protected
    Future<TypedInstance?> doGetSingleton(String name, {bool allowEarlyReference = true, ObjectFactory<Object>? factory}) async {
      if(factory != null) {
        return synchronized(_singletons, () async {
          // 1️⃣ Check if already created
          ObjectHolder<Object>? singleton = _singletons[name];

          Object? result = singleton?.getValue();
          Class? resultType = singleton?.getType();

          if (result == null) {
            // 2️⃣ Prevent creation during destruction phase
            if (_singletonsCurrentlyInDestruction) {
              throw PodCreationNotAllowedException(
                name: name,
                'Singleton pod creation not allowed while singletons of this factory are in destruction (Do not request a pod from a PodFactory in a destroy method implementation!)'
              );
            }

            if (_logger.getIsTraceEnabled()) {
              _logger.trace("Creating shared instance of pod $name");
            }

            // 3️⃣ Mark as in creation
            try {
              beforeSingletonCreation(name);
            } on PodCurrentlyInCreationException catch (_) {
              _singletonFactories[name] = factory;
              final cached = await getSingletonCache(name, allowEarlyReference);

              if (cached != null) {
                final resultType = cached.getType();

                if (resultType != null) {
                  _singletonTypes[name] = resultType;
                }

                return TypedInstance(cached.getValue(), resultType);
              }

              beforeSingletonCreation(name);
            }

            bool newSingleton = false;
            bool recordSuppressedExceptions = (_suppressedExceptions.get()?.isEmpty ?? true);
            if (recordSuppressedExceptions) {
              _suppressedExceptions.get()?.clear();
            }

            try {
              singleton = await factory.get();
              result = singleton.getValue();
              resultType = singleton.getType();

              newSingleton = true;
            } on IllegalStateException catch (_) {
              // If factory indicates the state changed and the singleton implicitly appeared,
              // prefer the cache instance if present; otherwise rethrow.
              singleton = _singletons[name];
              if (singleton == null) {
                rethrow;
              }

              result = singleton.getValue();
              resultType = singleton.getType();
            } catch (e) {
              if (recordSuppressedExceptions) {
                for (final ex in _suppressedExceptions.get()!) {
                  onSuppressedException(ex);
                }
              }
              rethrow;
            } finally {
              if (recordSuppressedExceptions) {
                _suppressedExceptions.get()?.clear();
              }
              afterSingletonCreation(name);
            }

            // If we created the singleton, register it (tolerate implicit duplicate)
            if (newSingleton) {
              try {
                addSingleton(name, object: singleton);
              } on IllegalStateException catch (_) {
                // Another concurrent path may have registered the same pod.
                // Accept the existing instance if it's identical; otherwise rethrow.
                final existing = _singletons[name];
                if (result != existing?.getValue()) {
                  rethrow;
                }
              }
            }
          }

          if (resultType != null) {
            _singletonTypes[name] = resultType;
          }

          return TypedInstance(result, resultType);
        });
      } else {
        final singleton = await getSingletonCache(name, allowEarlyReference);

        if (singleton != null) {
          return TypedInstance(singleton.getValue(), singleton.getType());
        } else {
          return null;
        }
      }
    }