PHP code example of sbuerk / typo3-symfony-di-test

1. Go to this page and download the library: Download sbuerk/typo3-symfony-di-test library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

sbuerk / typo3-symfony-di-test example snippets


final class ServiceFactory {
    public function create(string $context): ServiceInterface
    {
        return match($context) {
          'special' => new SpecialService(),
          default => new DefaultService(),
        };
    }
}

final class ServiceFactory {
    public function __construct(
        private DefaultServiceFactory $serviceFactory,
    ) {}

    public function create(string $context): ServiceInterface
    {
        return match($context) {
          'special' => new SpecialService(),
          default => $this->serviceFactory->create($context),
        };
    }
}

final class ServiceFactory implements ServiceFactoryInterface  {
    public function __construct(
        private ServiceFactoryInterface $serviceFactory,
    ) {}

    public function create(string $context): ServiceInterface
    {
        return match($context) {
          'special' => new SpecialService(),
          default => $this->serviceFactory->create($context),
        };
    }
}



declare(strict_types=1);

namespace SBUERK\DiTests\Services;

interface ServiceInterface
{
    public function ping(): string;
}



declare(strict_types=1);

namespace SBUERK\DiTests\Services;

interface ServiceFactoryInterface
{
    public function create(string $someData): ServiceInterface;
}



declare(strict_types=1);

namespace SBUERK\DiTests\Services;

use Symfony\Component\DependencyInjection\Attribute\AsAlias;use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
use TYPO3\CMS\Core\Database\ConnectionPool;

#[AsAlias(id: ServiceInterface::class, public: true)]
final readonly class DefaultService implements ServiceInterface
{
    public function __construct(
        private ConnectionPool $connectionPool,
    ) {}

    public function ping(): string
    {
        return __CLASS__;
    }
}



declare(strict_types=1);

namespace SBUERK\DiTests\Services;

use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\Attribute\AsAlias;

#[AsAlias(id: ServiceFactoryInterface::class)]
final readonly class DefaultServiceFactory implements ServiceFactoryInterface
{
    public function __construct(
        private ContainerInterface $container,
    ) {}

    public function create(string $someData): ServiceInterface
    {
        return $this->container->get(DefaultService::class);
    }
}



declare(strict_types=1);

namespace SBUERK\DiTests\Services;

use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Resource\ResourceFactory;

#[Autoconfigure(public: true)]
final readonly class SecondService implements ServiceInterface
{
    public function __construct(
        private ConnectionPool $connectionPool,
        private ResourceFactory $resourceFactory,
    ) {}

    public function ping(): string
    {
        return __CLASS__;
    }
}



declare(strict_types=1);

namespace SBUERK\DiTests\Services;

use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Resource\ResourceFactory;

#[Autoconfigure(public: true)]
final readonly class SecondService implements ServiceInterface
{
    public function __construct(
        private ConnectionPool $connectionPool,
        private ResourceFactory $resourceFactory,
        private ServiceInterface $defaultService,
        // ^^ or private DefaultService $defaultService,
    ) {}

    public function ping(): string
    {
        // use public methods from the default service
        return $this->defaultService->ping() , ' -> ' . __CLASS__;
    }
}



declare(strict_types=1);

namespace SBUERK\DiTests\Services;

use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface;use TYPO3\CMS\Install\FolderStructure\DefaultFactory;

#[AsAlias(id: ServiceFactoryInterface::class)]
final readonly class SecondServiceFactory implements ServiceFactoryInterface
{
    public function __construct(
        private ContainerInterface $container,
        private DefaultFactory $defaultFactory,
    ) {}

    public function create(string $someData): ServiceInterface
    {
        return match ($someData) {
            'second' => $this->container->get(SecondService::class),
            default => $this->defaultFactory->create($someData),
        };
    }
}



declare(strict_types=1);

namespace SBUERK\DiTests\Services;

use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
use Symfony\Component\DependencyInjection\Attribute\AutowireDecorated;
use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface;

#[AsDecorator(decorates: ServiceFactoryInterface::class, priority: 0, onInvalid: SymfonyContainerInterface::IGNORE_ON_INVALID_REFERENCE)]
final readonly class SecondServiceFactory implements ServiceFactoryInterface
{
    public function __construct(
        private ContainerInterface $container,
        #[AutowireDecorated]
        private ServiceFactoryInterface $serviceFactory,
    ) {}

    public function create(string $someData): ServiceInterface
    {
        return match ($someData) {
            'second' => $this->container->get(SecondService::class),
            default => $this->serviceFactory->create($someData),
        };
    }
}


declare(strict_types=1);

namespace SBUERK\DiTests\Services;

use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
use Symfony\Component\DependencyInjection\Attribute\AutowireDecorated;
use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface;

#[AsDecorator(decorates: DefaultServiceFactory::class, priority: 1, onInvalid: SymfonyContainerInterface::IGNORE_ON_INVALID_REFERENCE)]
final readonly class SomeServiceFactory implements ServiceFactoryInterface
{
    public function __construct(
        private ContainerInterface $container,
        #[AutowireDecorated]
        private ServiceFactoryInterface $serviceFactory,
    ) {}

    public function create(string $someData): ServiceInterface
    {
        return match ($someData) {
            'some' => $this->container->get(SomeService::class),
            'third' => $this->container->get(ThirdService::class),
            default => $this->serviceFactory->create($someData),
        };
    }
}



declare(strict_types=1);

namespace SBUERK\DiTests\Command;

use SBUERK\DiTests\Services\ServiceFactoryInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand(name: 'di:test')]
final class TestCommand extends Command
{
    public function __construct(
        private ServiceFactoryInterface $serviceFactory,
    ) {
        parent::__construct();
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $output->writeln('');

        $output->writeln(sprintf('ServiceFactoryInterface implemetnation: %s', $this->serviceFactory::class));
        $output->writeln('');

        $someFactory = $this->serviceFactory->create('some');
        $output->writeln(sprintf('Service class for context "some": %s', $someFactory::class));
        $output->writeln('Service->ping() result: ' . $someFactory->ping());
        $output->writeln('');

        $secondService = $this->serviceFactory->create('second');
        $output->writeln(sprintf('Service class for context "second": %s', $secondService::class));
        $output->writeln('Service->ping() result: ' . $secondService->ping());
        $output->writeln('');

        return Command::SUCCESS;
    }
}



declare(strict_types=1);

namespace SBUERK\DiTests\Services;

use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\DependencyInjection\Attribute\AutowireDecorated;
use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface;

#[AsDecorator(decorates: ServiceFactoryInterface::class, priority: 0, onInvalid: SymfonyContainerInterface::IGNORE_ON_INVALID_REFERENCE)]
final readonly class SecondServiceFactory implements ServiceFactoryInterface
{
    public function __construct(
        #[Autowire(service: SecondService::class, lazy: true)]
        private ServiceInterface $secondService,
        #[AutowireDecorated]
        private ServiceFactoryInterface $serviceFactory,
    ) {}

    public function create(string $someData): ServiceInterface
    {
        return match ($someData) {
            'second' => $this->secondService,
            default => $this->serviceFactory->create($someData),
        };
    }
}