Services & Dependency Injection
Der Service-Container
Shopware nutzt den Dependency-Injection-Container von Symfony. Eigene Klassen werden als Services registriert und bekommen ihre Abhängigkeiten automatisch hineingereicht – statt sie selbst zu erzeugen.
Einen Service registrieren
Services werden in der Resources/config/services.xml deklariert. Sobald die Datei existiert, wird sie von Shopware automatisch geladen.
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services">
<services>
<service id="Swag\Example\Service\PriceFormatter">
<argument type="service" id="Shopware\Core\System\SystemConfig\SystemConfigService"/>
</service>
</services>
</container>
Die Service-Klasse
Die Abhängigkeit kommt über den Konstruktor – klar, testbar und ohne globalen Zustand.
<?php declare(strict_types=1);
namespace Swag\Example\Service;
use Shopware\Core\System\SystemConfig\SystemConfigService;
class PriceFormatter
{
public function __construct(private readonly SystemConfigService $config)
{
}
public function format(float $value): string
{
$decimals = (int) $this->config->get('SwagExample.config.decimals');
return number_format($value, $decimals, ',', '.') . ' €';
}
}
Autowiring
Gibt man autowire="true" an, löst Symfony die Konstruktor-Argumente anhand ihrer Typen selbst auf – die explizite <argument>-Zeile entfällt dann meist:
<service id="Swag\Example\Service\PriceFormatter" autowire="true"/>
Faustregel: Fachliche Logik gehört in Services, nicht in Templates oder Controller. So bleibt sie an einer Stelle, testbar und wiederverwendbar.
Services sind die Bausteine. Damit sie zur richtigen Zeit laufen, hängt man sie an Events.