src/PeekAndPoke/Aviator/ServiceContainer/ServiceDefinitionProvider/ForServiceFactoryAnnotation.php
public function provide(Builder $builder, Frame $frame) : ServiceDefinition
    {
        $marker    = $frame->getServiceAnnotation();
        $factoryId = $marker->getId();

        if (! $marker instanceof ServiceFactory) {
            throw new BuilderException("This provider can only handle {$this->handles()}");
        }

        /** @var FactoredService[] $result */
        $factoredServices = [];

        // scan for factory methods
        foreach ($frame->getClass()->getMethods() as $method) {
            /** @var Di\DiServiceAnnotation $main */
            $main = $this->reader->getMethodAnnotation($method, Di\DiServiceAnnotation::class);

            if ($main) {
                // check if a valid return type is specified
                if ($method->getReturnType() === null || $method->getReturnType()->isBuiltin()) {

                    throw new BuilderException(
                        "Factory method {$frame->getClass()->getName()}::{$method->getName()} must have a return type specified"
                    );
                }


                // and get the initial service definitions
                $serviceType    = new \ReflectionClass((string) $method->getReturnType());
                $serviceOptions = DiOptionsCollection::from($this->reader, $method);
                $service        = $builder->provideServiceDefinitionFor(new Frame($serviceType, $main, $serviceOptions, $method));

                // transform into a FactoredServiceDefinition and gather them
                $factoryMethod      = new ServiceFactoryMethod(
                    $factoryId,
                    $method->getName(),
                    $method->getReturnType()->allowsNull(),
                    $builder->createPublicMethodInjection($method)
                );
                $factoredServices[] = new FactoredService($service, $factoryMethod);
            }
        }

        // create the service definition for the factory
        $factory = new ServiceDefinition\DefaultService(
            $frame->getClass()->getName(),
            $builder->buildInjectionForClass($frame->getClass(), null),
            $marker,
            $frame->getOptions(),
            $factoredServices
        );

        return $factory;
    }
public function provide(Builder $builder, Frame $frame) : ServiceDefinition
    {
        $marker    = $frame->getServiceAnnotation();
        $factoryId = $marker->getId();

        if (! $marker instanceof ServiceFactory) {
            throw new BuilderException("This provider can only handle {$this->handles()}");
        }

        /** @var FactoredService[] $result */
        $factoredServices = [];

        // scan for factory methods
        foreach ($frame->getClass()->getMethods() as $method) {
            /** @var Di\DiServiceAnnotation $main */
            $main = $this->reader->getMethodAnnotation($method, Di\DiServiceAnnotation::class);

            if ($main) {
                // check if a valid return type is specified
                if ($method->getReturnType() === null || $method->getReturnType()->isBuiltin()) {

                    throw new BuilderException(
                        "Factory method {$frame->getClass()->getName()}::{$method->getName()} must have a return type specified"
                    );
                }


                // and get the initial service definitions
                $serviceType    = new \ReflectionClass((string) $method->getReturnType());
                $serviceOptions = DiOptionsCollection::from($this->reader, $method);
                $service        = $builder->provideServiceDefinitionFor(new Frame($serviceType, $main, $serviceOptions, $method));

                // transform into a FactoredServiceDefinition and gather them
                $factoryMethod      = new ServiceFactoryMethod(
                    $factoryId,
                    $method->getName(),
                    $method->getReturnType()->allowsNull(),
                    $builder->createPublicMethodInjection($method)
                );
                $factoredServices[] = new FactoredService($service, $factoryMethod);
            }
        }

        // create the service definition for the factory
        $factory = new ServiceDefinition\DefaultService(
            $frame->getClass()->getName(),
            $builder->buildInjectionForClass($frame->getClass(), null),
            $marker,
            $frame->getOptions(),
            $factoredServices
        );

        return $factory;
    }
@param Builder $builder
@param Frame   $frame

@return ServiceDefinition

@throws BuilderException