# containsType method

1. @override

Future<bool> containsType(

1. Class requestedType, [
2. bool allowPodProviderInit = false

])
override

Checks if the factory contains a pod of the specified type.

This method is useful for checking the availability of a pod before attempting to retrieve it.

## Usage Example:

    if (await factory.containsType(Class<UserService>())) {
      final userService = await factory.getPod<UserService>('userService');
      userService.doSomething();
    }

@param type The class type of the pod to check @return A Future that completes with true if the pod exists

## Implementation

    @override
    Future<bool> containsType(Class requestedType, [bool allowPodProviderInit = false]) async {
      // 1) Fast path: check all cached singletons
      final singletonNames = getSingletonNames(); // Iterable<String>
      for (final name in singletonNames) {
        final holder = await getSingletonCache(name, false);
        if (holder == null) continue;
        final holderType = holder.getType()?.getType();
        if (holderType == NullablePod.CLASS.getType()) continue; // ignored placeholder

        final instance = holder.getValue();

        // 1.a) If instance is a PodProvider
        if (instance is PodProvider) {
          // If provider itself would satisfy requestedType (e.g. requestedType is PodProvider or compatible)
          if (instance.supportsType(requestedType)) {
            return true;
          }

          // Try to determine what the provider produces (may instantiate provider if allowed)
          final produced = await getPodProviderType(instance, allowPodProviderInit);
          if (produced != null && requestedType.isAssignableFrom(produced)) {
            return true;
          }

          // If requestedType has generics, consult local definition metadata (if available)
          if (requestedType.hasGenerics() && containsDefinition(name)) {
            final merged = getLocalMergedPodDefinition(name);
            final Class declared = merged.type;
            if (POD_PROVIDER_CLASS.isAssignableFrom(declared)) {
              // If requested type is not a provider, try matching component type
              if (!POD_PROVIDER_CLASS.isAssignableFrom(requestedType) && !requestedType.isAssignableFrom(declared)) {
                final comp = declared.componentType();
                if (comp != null && requestedType.isAssignableFrom(comp)) {
                  return true;
                }
              }
            } else {
              if (requestedType.isAssignableFrom(declared)) return true;
            }
          }

          // Not matched by this provider instance
          continue;
        }

        // 1.b) If instance is not a provider
        if (requestedType.isInstance(instance)) {
          return true;
        }

        // For generics, consult the local definition if exists
        if (requestedType.hasGenerics() && containsDefinition(name)) {
          final def = getLocalMergedPodDefinition(name);
          final Class declared = def.type;
          if (!declared.isInstance(instance)) {
            final Class? comp = requestedType.componentType();
            if (comp != null && !comp.isInstance(instance)) {
              // instance doesn't match component type -> continue searching
              continue;
            }
            if (requestedType.isAssignableFrom(declared)) return true;
          } else {
            if (requestedType.isAssignableFrom(declared)) return true;
          }
        }
      } // end singletons loop

      // 2) Check local PodDefinitions (declarations) even if not instantiated yet
      final localNames = getDefinitionNames();
      for (final name in localNames) {
        final def = getLocalMergedPodDefinition(name);

        // 2.a) Declared type directly matches
        final Class declaredType = def.type;
        if (requestedType.isAssignableFrom(declaredType)) {
          return true;
        }

        // 2.b) If declared type is a PodProvider, check provided type metadata first
        if (POD_PROVIDER_CLASS.isAssignableFrom(declaredType)) {
          // If the definition exposes providedType metadata, prefer that
          final Class? providedFromDef = def.type; // optional metadata; null if unknown
          if (providedFromDef != null && requestedType.isAssignableFrom(providedFromDef)) {
            return true;
          }

          // If allowed, instantiate provider to inspect produced type
          if (allowPodProviderInit) {
            try {
              final providerInstance = await getPod(name, []);
              if (providerInstance is PodProvider) {
                final Class? produced = await getPodProviderType(providerInstance, true);
                if (produced != null && requestedType.isAssignableFrom(produced)) {
                  return true;
                }
              }
            } catch (_) {
              // ignore provider instantiation failures and continue scanning others
            }
          }

          // For generics, check component type on declared provider
          if (requestedType.hasGenerics()) {
            final Class? declaredComp = declaredType.componentType();
            final Class? wantedComp = requestedType.componentType();
            if (declaredComp != null && wantedComp != null && wantedComp.isAssignableFrom(declaredComp)) {
              return true;
            }
          }

          // continue checking other definitions
          continue;
        }

        // 2.c) Generics: check component/generic compatibility between requestedType and declaredType
        if (requestedType.hasGenerics()) {
          final Class? declaredComp = declaredType.componentType();
          final Class? wantedComp = requestedType.componentType();
          if (declaredComp != null && wantedComp != null && wantedComp.isAssignableFrom(declaredComp)) {
            return true;
          }
        }
      } // end local definitions loop

      // 3) Delegate to parent factory if present
      final parent = getParentFactory();
      if (parent != null) {
        try {
          return await parent.containsType(requestedType, allowPodProviderInit);
        } catch (_) {
          // If parent lookup errors, treat as no match (robust fallback)
          return false;
        }
      }

      // 4) Nothing matched
      return false;
    }