# autowireByType method

1. @protected

Future<void> autowireByType(

1. String podName,
2. RootPodDefinition root,
3. PodHolder ph,
4. MutablePropertyValues pvs,

)

Performs autowiring by type for the pod instance.

This method resolves dependencies based on their types and injects them into the corresponding fields or setters.

@param podName The name of the pod being wired @param root The pod definition @param ph The pod holder @param pvs The property values to populate

## Implementation

    @protected
    Future<void> autowireByType(String podName, RootPodDefinition root, PodHolder ph, MutablePropertyValues pvs) async {
      final nonSatisfiedProperties = getUnsatisfiedNonSimpleProperties(root, ph);
      final autowiredPods = <String>{};

      for (final entry in nonSatisfiedProperties.entries) {
        String propertyName = entry.key;
        Class type = entry.value;
        bool isEager = ph.$1 is PriorityOrdered;

        // Skip Object type
        if (type.getType() == Object) {
          continue;
        }

        try {
          final methods = ph.$2.getMethods();

          Method? method = methods.firstWhereOrNull((m) => m.getName().equalsIgnoreCase('set$propertyName'));
          method ??= methods.firstWhereOrNull((m) => m.getName().equalsIgnoreCase(propertyName) && m.isSetter());

          if (method != null) {
            Class type = method.getReturnClass();
            Object? autowiredValue = await resolveDependency(DependencyDescriptor(
              source: method,
              podName: podName,
              propertyName: propertyName,
              type: type,
              args: null,
              component: type.componentType(),
              key: type.keyType(),
              isEager: isEager,
            ), autowiredPods);
            if (autowiredValue != null) {
              pvs.add(propertyName, autowiredValue, qualifiedName: type.getQualifiedName(), packageName: type.getPackage()?.getName());

              if(logger.getIsTraceEnabled()) {
                logger.trace("Autowiring by type from method '$method' for pod name '$propertyName' to pod named '$podName'");
              }
            }

            for (final name in autowiredPods) {
              registerDependentPod(name, podName);

              if (logger.getIsTraceEnabled()) {
    							logger.trace("Autowiring by type from method '$method' for pod name '$name' via property '$propertyName' to pod named '$podName'");
    						}
            }

            autowiredPods.clear();
          } else {
            // Fallback to cached fields for field injection and performance
            final fields = ph.$2.getFields();
            Field? field = fields.firstWhereOrNull((f) => f.getName().equalsIgnoreCase(propertyName) && !f.getReturnClass().isPrimitive());
            if (field != null) {
              Class type = field.getReturnClass();
              Object? autowiredValue = await resolveDependency(DependencyDescriptor(
                source: field,
                podName: podName,
                propertyName: propertyName,
                type: type,
                args: null,
                component: type.componentType(),
                key: type.keyType(),
                isEager: isEager,
                isRequired: !field.isNullable()
              ), autowiredPods);
              if (autowiredValue != null) {
                pvs.add(propertyName, autowiredValue, qualifiedName: type.getQualifiedName(), packageName: type.getPackage()?.getName());

                if(logger.getIsTraceEnabled()) {
                  logger.trace("Autowiring by type from pod name '$propertyName' to pod named '$podName'");
                }
              }
            }

            for (final name in autowiredPods) {
              registerDependentPod(name, podName);

              if (logger.getIsTraceEnabled()) {
    							logger.trace("Autowiring by type from method '$method' for pod name '$name' via property '$propertyName' to pod named '$podName'");
    						}
            }

            autowiredPods.clear();
          }
        } catch (e) {
          if(logger.getIsTraceEnabled()) {
            logger.trace("Failed to autowire property '$propertyName' by type: $e");
          }

          throw UnsatisfiedDependencyException.withResource(
            root.description,
            podName,
            "Unsatisfied dependency of type '${type.getQualifiedName()}' for property '$propertyName'",
            cause: e is Throwable ? e : RuntimeException(e.toString()),
          );
        }
      };
    }