Codice sensibile all'ambiente

3

Esistono situazioni in cui l'ambiente distribuito ( sviluppo , test o produzione , ad esempio) potrebbe dettare il risultato di determinate azioni.

Ad esempio, forse un processo di "registrazione utente" riuscito invierà una notifica via email al nuovo utente. Azioni specifiche per l'ambiente:

  • Sviluppo: in realtà non invia l'email. I log delle email forniranno abbastanza per gli sviluppatori.
  • Test: invia tutte le email a qualche posta in arrivo di [email protected] e non all'indirizzo dell'utente.
  • Produzione: invia l'email all'utente

Ho elencato tre possibili soluzioni di seguito.

Valore di configurazione CurrentEnvironment

Un modo per risolvere questo problema, che ho visto molto, è avere un qualche valore di configurazione (che sia in qualche file di configurazione xml o nel database) come CurrentEnvironment che specifica l'ambiente corrente in cui il sistema è schierato a. Ciò richiederebbe caso / se controlli nel codice per determinare l'azione desiderata:

if(CurrentEnvironment == Environment.Test)
{
    // Send all emails to some [email protected] inbox.
}
else if(CurrentEnvironment == Environment.Production)
{
    // Send the email to the user.
}

Questa non è una soluzione gestibile secondo me.

Elimina tutti gli indirizzi email

Un altro metodo consiste nell'eseguire uno script di modifica, una volta ripristinato un database, per eseguire quanto segue:

  • Rimuovi tutti gli indirizzi email dell'utente (in fase di sviluppo),
  • Sostituisci tutti gli indirizzi email dell'utente con [email protected] (in test)

Questo è un ulteriore passo nella procedura di rilascio che, se persa, potrebbe avere dei risultati pericolosi. Inoltre, questa soluzione risolve solo il problema della posta elettronica. Ci sono forse molte altre situazioni in cui l'ambiente conta.

Trasformazione della configurazione

Un'altra idea è quella di utilizzare trasformazioni web.config . In questo modo la configurazione può essere diversa per diversi ambienti. Ad esempio, avremo le seguenti configurazioni:

 web.config
   web.Development.config
   web.Test.config
   web.Production.config

La trasformazione può quindi utilizzare diversi "provider" o impostare determinati attributi in base all'ambiente. Ad esempio, un overrideDeliveryAddress può essere impostato in web.Test.config :

<EmailService>
  <providers>
    <add 
      name="EmailServiceProvider"
      type="CustomProviders.EmailServiceProvider, CustomProviders"
      smtp="smtp.domain.com" password="xyz"
      overrideDeliveryAddress="[email protected]"
      enabled="true"
    />
 </providers>
</EmailService>

Questa soluzione richiede molto più lavoro, ma è più manutenibile e meno invasiva. Il codice è ora ignaro dell'ambiente.

Quali altri modi possono essere raggiunti sopra? Il codice dovrebbe MAI essere consapevole dell'ambiente?

    
posta davenewza 11.04.2014 - 08:41
fonte

3 risposte

1

Per prima cosa, non dovresti usare i tuoi dati di produzione reali (specialmente quelli relativi alle persone) nello sviluppo o nel test (puoi usare accuratamente estratti di dati di produzione, ovviamente). Quindi i tuoi pool di dati (forse un database, forse un pool di file, forse entrambi), dovrebbero essere separati tra questi ambienti. Quindi l'unica cosa che devi modificare è il file di configurazione in cui passi tra questi 3 pool di dati (ad esempio, la stringa di connessione al database o il percorso dei file). Ciò significa che non sarà necessario alcun "codice sensibile all'ambiente", l'unica cosa che è consapevole di enironment è quella voce nel file di configurazione principale.

Ad esempio, il tuo ambiente di sviluppo dovrebbe avere un database di sviluppo con un elenco di indirizzi e-mail, e il tuo ambiente di test un diverso database con un elenco diverso, e il tuo ambiente di produzione un database con gli indirizzi di posta reali.

Il problema che si sta descrivendo sembra essere una situazione in cui si tenta di caricare una copia del database di produzione nell'ambiente di sviluppo e sostituire il database di sviluppo con quello. Questo è probabilmente uno scenario da evitare, fornire migliori meccanismi di importazione / esportazione per trasferire piccole porzioni di dati da un database all'altro, in cui i dati personali non vengono normalmente trasferiti. Se veramente hai bisogno di una copia originale del DB di produzione nel tuo ambiente di sviluppo (perché altrimenti non puoi riprodurre un certo bug), vai con la soluzione 2 e cancella o anonima qualsiasi personale dati come indirizzi mail (in molti scenari è necessario farlo per motivi di privacy).

    
risposta data 11.04.2014 - 10:37
fonte
3

Proporrei un approccio basato sull'iniezione delle dipendenze e sugli oggetti null. Se si consente alla configurazione di definire quale oggetto deve essere utilizzato per un'attività specifica in ciascun ambiente, è possibile definire comportamenti specifici all'interno di tali oggetti. Quindi usi una Fabbrica per inizializzare i tuoi oggetti a seconda dell'ambiente.

Userò la posta come esempio, ma questo approccio può essere applicato in molti altri contesti: registri, messaggi di errore, comunicazioni con API esterne, ecc ... Un mailer nullo sarà un oggetto che ha la stessa interfaccia di il tuo solito mailer e semplicemente ignorerà le istruzioni di invio della posta. Gli oggetti che devono inviare e-mail avranno un parametro mailer inizializzato all'istanza dell'oggetto: nel tuo ambiente di produzione, il tuo mailer sarà il tuo solito mailer. Nel tuo ambiente di test, il tuo mailer sarà nullo ("non fare nulla") mailer.

Per gestire l'istanziazione degli oggetti a seconda dell'ambiente in cui lavori, crea un oggetto factory che legge il tuo file di configurazione e restituisce il mailer (logger, libreria di api ...) a seconda di cosa viene specificato lì. Potresti avere un file di configurazione per ogni ambiente.

    
risposta data 11.04.2014 - 13:57
fonte
1

Il codice non dovrebbe essere consapevole dell'ambiente, ecco perché abbiamo configurazioni. Inoltre, di solito non vuoi spedire il tuo codice con i segreti di sviluppo (stringa di connessione DB, ecc.). O a volte non è desiderabile dare agli sviluppatori accesso ai segreti di produzione.

Sebbene sia un compito tipico della programmazione, di avere configurazioni separate per ambienti diversi, non abbiamo soluzioni, strumenti o processi comuni su come risolverlo. Preferisco la copia o la trasformazione della configurazione, che hai menzionato.

    
risposta data 27.05.2015 - 12:35
fonte