È una cattiva progettazione se iniettiamo dipendenze basate sull'ambiente in esecuzione (produzione, test, sviluppo, ecc.)?
Considera il seguente contenitore in Laravel come esempio:
$app->singleton(
\App\Services\Mailer\MailerInterface::class,
function($app) {
if ($app->environment() === \App\Support\Environments::PRODUCTION) {
return $app->make(\App\Services\Mailer\SendGridMailer::class);
}
if ($app->environment() === \App\Support\Environments::TESTING) {
return $app->make(\Tests\Helpers\Mailer\TestMailer::class);
}
);
Qui collego diverse implementazioni a MailerInterface in base all'ambiente dell'applicazione.
Ciò che mi infastidisce è che le condizioni if else vengono eseguite sempre indipendentemente dall'ambiente. Trovo che questo sia più soggetto a bug e non ai miei gusti di eseguire tali condizioni anche in produzione.
Un'altra opzione che conosco per aggirare questo caso è usare altri binding solo per il test.
Solo durante l'esecuzione delle suite di test possiamo aggiungere un altro contenitore come parte del bootstrap della suite di test. (dapprima viene eseguito tutto il codice usuale, quindi il booster di prova esegue ulteriori collegamenti).
Il problema che devo affrontare con questa soluzione è che solo per modificare il binding di MailerInterface a TestMailer, dobbiamo anche aggiornare tutte le altre astrazioni che dipendono da MailerInterface.
Quindi per fare ciò devo aggiornare lascia dire anche UserServiceInterface ecc., ricollegalo tutti in modo che la modifica venga propagata. (Nel caso in cui le altre classi siano singleton e nelle chiusure sia incluso il bind iniziale di MailerInterface). Nel mio caso ho bisogno di scrivere nel contenitore test 5 associazioni, 1 per il Mailer stesso e 4 per qualsiasi altra cosa che dipende da questo.
Che cosa pensi e quale soluzione mi puoi suggerire? Grazie in anticipo