2012-11-29 9 views
5

Ho un'applicazione C# WinForms in Visual Studio 2010 utilizzata da due clienti diversi. La funzionalità di base dell'applicazione è la stessa per ogni cliente, ma alcune righe di codice (nomi di stored procedure, risorse, determinati comportamenti) sono diverse tra le versioni. Finora, ho mantenuto l'applicazione nello stesso progetto e ho utilizzato le direttive del preprocessore durante la creazione/pubblicazione per passare da una distribuzione all'altra. Tuttavia, lo scopo del progetto è cresciuto fino a renderlo non più fattibile.Manutenzione e distribuzione simultanea di due versioni di un'applicazione

Poiché gran parte del codice è condivisa, sto cercando di evitare la duplicazione dei file del codice sorgente. Mi chiedo quale sia l'approccio migliore per mantenere un'applicazione che richiede l'implementazione simultanea di diverse versioni.

+0

Le direttive del preprocessore non devono essere utilizzate per gestire i rami. –

+0

Concordato. Questo è iniziato come una piccola applicazione interna a cui i clienti esterni hanno espresso interesse, quindi avevamo bisogno di una soluzione rapida per la separazione. – WickerPopstar

risposta

4

Utilizzare le interfacce per definire le classi. Avere un'interfaccia significa che è possibile avere più implementazioni della stessa interfaccia, una per ciascuno dei client. Ciò richiederà l'analisi della base di codice esistente e l'identificazione delle separazioni logiche nel codice in cui tali interfacce possono essere definite.

È quindi possibile caricare un'interfaccia in base alle esigenze in base al client. Ad esempio, potresti farlo tramite la configurazione. Sulla base di un valore di configurazione si carica Implementation1 o Implementation2. Ci sono molti, molti modi per realizzare questo particolare bit. Dovresti leggere l'iniezione delle dipendenze, l'inversione del controllo e dare un'occhiata a strumenti come Ninject, Autofac, Unity.

In realtà, potrebbe essere difficile in un primo momento considerare come si sono state usando le direttive del preprocessore ma, visto come la vostra applicazione sta crescendo, avrete bisogno che questo refactoring avvenga. Tieni presente che se non lo fai ora, questo refactoring sarà molto più costoso in seguito poiché la tua applicazione diventa più complessa.

+0

Avevo la sensazione che fosse un problema di architettura e grazie per la terminologia (dipendenza da iniezione, IOC, ecc.). Questi erano i termini che mi mancavano quando cercavo una soluzione. – WickerPopstar

2

Le diverse funzionalità dovrebbero far parte dell'architettura dell'applicazione. Se hai bisogno di funzionalità diverse per clienti diversi, estraetele via - crea un'interfaccia che avvolge il comportamento, quindi implementalo in due modi diversi in due diversi assembly. Quindi (a seconda del meccanismo di implementazione), puoi spedire la tua app con una DLL o l'altra. Per evitare di dover ricompilare, aggiungere riferimenti, ecc., È possibile utilizzare i framework Injection Dependency come Ninject, Castle Windsor, MEF ecc. Si tratta di un'architettura "plug-like", se il codice è sufficientemente diverso.

Se stai parlando di testo, colori, differenze di base, non dovrebbero semplicemente essere codificati, ma piuttosto guidati dai dati. Se la tua app è connessa a Internet, potrebbe scaricare le impostazioni appropriate quando l'utente esegue il login. Altrimenti, qualcosa per indicare il testo/i colori/il comportamento potrebbe essere inserito in un file di configurazione specifico per il cliente. È possibile utilizzare trasformazioni di configurazione per semplificare tale processo.

+0

Le differenze di base sono già basate sui dati, per fortuna. È principalmente funzionalità. Non ho familiarità con questi framework, ma questa applicazione utilizza una distribuzione ClickOnce. Ciò cambia il modo in cui tali quadri sono implementati? – WickerPopstar

+0

Ho esattamente la stessa situazione nel mio progetto. Ninject, altri framework DI funzioneranno, ma noi scarichiamo dinamicamente le DLL da un URL dopo che l'app è stata installata: altrimenti ogni cliente ottiene una DLL con tutta la logica degli altri clienti nella propria installazione. Non cambia molto, solo che vuoi caricare gli assembly da un URL piuttosto che da un disco. O cosa puoi fare da disco comunque :) –

0

Potrebbe essere possibile separare alcune delle differenze utilizzando risorse, configurazioni o file di proprietà di qualche tipo. Con questo, voglio dire che memorizzi qualche tipo di valore nel file, come il nome della stored procedure da usare in una situazione particolare. Quindi il tuo codice legge il nome dal file e lo esegue. È possibile modificare i valori nel file senza dover ricostruire il codice per ogni distribuzione.

Problemi correlati