Servizi pigri

Nuovo nella versione 2.3: I servizi pigri sono stati aggiunti in Symfony 2.3.

Perché i servizi pigri?

A volte può essere necessario iniettare, all’interno del proprio oggetto, un servizio un po’ pesante da istanziare e che non sempre viene utilizzato . Si supponga, ad esempio, di avere un GestoreDiNewsletter e che si voglia iniettare un servizio mailer al suo interno. Solo alcuni metodi del GestoreDiNewsletter usano effettivamente il mailer ma, anche senza farne uso, il servizio mailer verrebbe comunque istanziato in modo da poter costruire il GestoreDiNewsletter.

Per risolvere questo problema è possibile usare un servizio pigro. Quando si usa un servizio pigro, in realtà viene iniettato un “proxy” del servizio mailer. Il proxy sembra e si comporta esattamente come se fosse il mailer, a parte il fatto che mailer non viene istanziato finché non si interagisce in qualche modo con il suo proxy.

Installazione

Per poter istanziare i servizi pigri è prima necessario installare il bridge ProxyManager:

$ composer require symfony/proxy-manager-bridge:~2.3

Nota

Se si usa il framework completo, questo pacchetto è già incluso, ma il vero gestore di proxy deve essere incluso. Eseguire quindi:

$ php composer.phar require ocramius/proxy-manager:~0.5

Compilare quindi il contenitore e verificare di avere un proxy per i servizi pigri.

Configurazione

Si può definire un servizio come pigro, modificandone la definizione:

  • YAML
    services:
       pippo:
         class: Acme\Pippo
         lazy: true
    
  • XML
    <?xml version="1.0" encoding="UTF-8" ?>
    <container xmlns="http://symfony.com/schema/dic/services"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
    
        <services>
            <service id="pippo" class="Acme\Pippo" lazy="true" />
        </services>
    </container>
    
  • PHP
    use Symfony\Component\DependencyInjection\Definition;
    
    $definizione = new Definition('Acme\Pippo');
    $definizione->setLazy(true);
    $container->setDefinition('pippo', $definizione);
    

Ora è possibile richiedere il servizio dal contenitore:

$servizio = $container->get('pippo');

A questo punto il $servizio recuperato dovrebbe essere un proxy virtuale con la stessa firma della classe che rappresenta il servizio. È anche possibile iniettare il servizio così come si farebbe con qualsiasi altro servizio. L’oggetto che verrà effettivamente iniettato sarà il proxy.

Per verificare che il proxy funzioni, si può semplicemente verificare l’interfaccia dell’oggetto ricevuto.

var_dump(class_implements($service));

Se la classe implementa ProxyManager\Proxy\LazyLoadingInterface, i servizi pigri stanno funzionando.

Nota

Se non si è installato il bridge ProxyManager, il contenitore si limiterà a saltare il parametro lazy e a istanziare il servizio come farebbe normalmente.

Il proxy viene inizializzato e il servizio vero e proprio viene istanziato non appena si dovesse interagire con l’oggetto.

Risorse aggiuntive

È possibile approfondire le modalità con cui i sostituti vengono istanziati, generati e inizializzati nella documentazione su ProxyManager.

Tabella dei contenuti

Argomento precedente

Configurazione avanzata del contenitore

Argomento successivo

Flusso di costruzione del contenitore

Questa pagina