Skip to content

Instantly share code, notes, and snippets.

@benblub
Last active August 26, 2022 12:36
Show Gist options
  • Save benblub/b799c4d46facb7ff89244dede3cac02c to your computer and use it in GitHub Desktop.
Save benblub/b799c4d46facb7ff89244dede3cac02c to your computer and use it in GitHub Desktop.
<?php
namespace App;
class BarService
{
public function bar(): string
{
return 'bar';
}
}
<?php
namespace App;
use ApiPlatform\Core\JsonSchema\TypeFactoryInterface;
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
use Symfony\Component\DependencyInjection\Attribute\MapDecorated;
#[AsDecorator(decorates: BarService::class)]
class BarServiceDecorator
{
private $inner;
public function __construct(#[MapDecorated] $inner)
{
$this->inner = $inner;
}
public function bar(): string
{
return $this->inner->bar() . ' Bar';
}
}
<?php
namespace App\Controller;
use App\Service\BarService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class TestController extends AbstractController
{
/**
* @Route("/foo")
*/
public function foo(BarService $barService)
{
return new Response('foo ' . $barService->bar());
}
}
@benblub
Copy link
Author

benblub commented Aug 26, 2022

BarServiceDecorator needs to either extends BarService, or implements BarServiceInterface

Thanks 👍

@benblub
Copy link
Author

benblub commented Aug 26, 2022

Here is another example of how to use the whole thing with interfaces.

<?php

namespace App\Controller;

use App\Service\BarServiceInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class TestController extends AbstractController
{
    /**
     * @Route("/foo")
     */
    public function foo(BarServiceInterface $barService)
    {
        return new Response('foo ' . $barService->bar());
    }
}
<?php

namespace App\Service;

use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
use Symfony\Component\DependencyInjection\Attribute\MapDecorated;

#[AsDecorator(decorates: BarServiceInterface::class)]
class BarServiceDecorator implements BarServiceInterface
{
    private $inner;

    public function __construct(#[MapDecorated] $inner)
    {
        $this->inner = $inner;
    }

    public function bar()
    {
        return $this->inner->bar() . ' BAZ';
    }
}
<?php

namespace App\Service;

interface BarServiceInterface
{
    public function bar();
}
<?php

namespace App\Service;

class BarService implements BarServiceInterface
{
    public function bar()
    {
        return 'bar';
    }
}
    # services.yaml
    App\Service\BarServiceInterface: '@App\Service\BarService'

https://symfony.com/doc/current/service_container/autowiring.html#working-with-interfaces
https://symfony.com/doc/current/service_container/service_decoration.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment