L'iniezione di dipendenza condizionale basata sull'ambiente è un modello errato?

3

È 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

    
posta Kristi Jorgji 27.06.2018 - 16:06
fonte

2 risposte

5

Non c'è assolutamente nulla di sbagliato in questo. L'intero punto di un contenitore di iniezione delle dipendenze configurabile è quello di permetterti di configurarlo in base alle tue esigenze.

In questo caso fornisci un servizio di posta elettronica di prova invece di un vero servizio di posta elettronica nell'ambiente di test.

Un motivo perfetto per fare esattamente quello che stai facendo, e in effetti è una buona ragione per cui l'iniezione di dipendenza viene introdotta in un'applicazione in primo luogo.

    
risposta data 27.07.2018 - 18:23
fonte
0

Direi che è un cattivo schema.

Ero un grande fan della configurazione dell'unità xml per ragioni simili, ma sono giunto alla conclusione che il caso di utilizzo per il test è marginale e la complessità della configurazione può diventare eccessivamente onerosa.

Inoltre, vi è una mancanza di sicurezza attorno a ciò che viene effettivamente distribuito e configurato quando hai effettivamente portato i flag delle caratteristiche al massimo e stai usando il tuo framework DI come architettura di plugin.

Considera l'opzione alternativa di avere semplicemente un servizio di posta elettronica nel tuo ambiente di prova. Generai molte e-mail di prova, ma ottieni la conferma in più che le e-mail sono effettivamente inviate.

Nei casi in cui utilizzi servizi esterni di terze parti, collega il loro env di gestione temporanea o prendi in giro il loro endpoint nell'env test e puoi confermare che le richieste siano state inviate correttamente.

    
risposta data 27.06.2018 - 17:23
fonte

Leggi altre domande sui tag