Ho implementato un pattern Chain of Command, con moduli che implementano un'interfaccia:
interface IRequestHandler
{
public function handle(&$offset, &$tripData, $request = null);
public function setSuccessor(OffsetRequestHandler $handler);
}
Ho impostato una catena di moduli che modificano gli oggetti $offset
e $tripData
se necessario (suppongo che non sia esattamente un modello di catena di comando, ma ottenga il lavoro fatto :)
Vorrei iniziare a usare l'iniezione di dipendenza ogni volta che è possibile facilitare il processo di scrittura dei test di unità. La mia domanda è: come gestirla, se ogni modulo potrebbe necessitare di diversi set di servizi? Posso andare con Auryn e lasciare che istanzia automaticamente tutte le dipendenze per ogni modulo (almeno spero di poterlo fare), ma in teoria non dovrebbe essere necessario ...
Aggiornamento:
Per costruire la catena, prendo i nomi delle classi dal file di configurazione, li istanziamo e li sistemo in una coda. Il controller non è a conoscenza delle dipendenze di cui ogni modulo ha bisogno. Al momento, non ce ne sono, perché ogni modulo crea da solo gli oggetti necessari (e questo è ciò che voglio cambiare). Non voglio iniettare ogni modulo con il contenitore, perché questo si trasformerà in un modello di localizzazione del servizio.
Aggiornamento 2:
Necessità:
Ricevo un set di dati da risorse esterne e devo elaborarlo per ottenere alcune metriche. Tuttavia, i dati potrebbero essere danneggiati, inviati in batch o simili e il mio script deve risolverlo (il più possibile). I tipi di problemi possono dipendere dalla risorsa esterna da cui provengono i dati. E la situazione è dinamica, nel senso che nuovi tipi di problemi e nuove risorse esterne potrebbero apparire in futuro.
La mia idea:
Crea moduli. Ogni modulo affronterà problemi specifici. Disporre i moduli in una coda (poiché l'ordine dei moduli può essere importante) ed eseguirli iniettando i dati in entrata come parametro.
La soluzione è strongmente ispirata da questo articolo su SitePoint .
Ma invece di creare le istanze una ad una come nell'esempio:
$firstHandler = new FirstHandler();
$secondHandler = new SecondHandler();
$thirdHandler = new ThirdHandler();
//the code below sets all successors through the first handler
$firstHandler->setSuccessor($secondHandler);
$secondHandler->setSuccessor($thirdHandler);
$result = $firstHandler->handle($request);
Estraggo i nomi delle classi dal file di configurazione e li creo con un ciclo foreach
:
$modulesQueue = $config->get("extensions");
foreach ( $modulesQueue as $moduleName ) {
$moduleName = "extensions\".$moduleName;
$startModule->setSuccessor(new $moduleName());
}
// Starting the chain:
$ret = $startModule->handle($offset, $tripDataObject, $requestData);
Il problema:
Se creo un'istanza delle classi come questa, non vedo cosa debba aver iniettato ogni modulo (in questo momento nulla, poiché non viene applicato DI, ogni modulo istanzia i servizi di cui ha bisogno). Quindi vedo due opzioni qui: o passo alla creazione manuale dei moduli (che non è affatto flessibile), o comincio a usare Reflection
per scoprire di cosa ha bisogno ogni modulo e fornirlo.