2010-01-12 18 views
5

Nella mia soluzione ho tre progetti C#. Una è un'app console che richiama semplicemente in un progetto di libreria di classi. Il progetto della libreria di classi esegue tutta l'elaborazione per l'applicazione. Quindi c'è un progetto WinForm che visualizza un modulo e quindi quando viene premuto un pulsante, chiama la stessa logica nel progetto della libreria di classi. Di conseguenza, ci sono due modi per eseguire la logica, tramite la console o tramite un'interfaccia utente di Windows (WinForm).Come si progetta la visualizzazione della vista in progetti C#

Il mio problema è che in parte la logica della libreria di classi, se viene utilizzata l'app UI, voglio che appaia un modulo WinForm personalizzato per fare una domanda all'utente.

Nell'app Console, voglio la stessa posizione nella logica per scrivere semplicemente nella console. Nella mia comprensione dell'architettura, non si desidera che il progetto della libreria di classi contenga la logica WinForm e richiede che abbia riferimenti a tutti i riferimenti WinForm. Ma come posso chiamare il progetto WinForms (o qualcos'altro) per visualizzare il modulo WinForm personalizzato? Ci sarebbe un riferimento circolare in cui la libreria di classi farebbe riferimento all'app principale di WinForm e l'app WinForm farebbe riferimento al progetto della libreria di classi.

Qual è il modo standard per farlo?

+1

mi piacerebbe pensare a come un evento dalla libreria di classe e implementare un ascoltatore all'interno della vostra Codice UI (sia esso console o Winforms). – Lazarus

risposta

2

È possibile creare un'interfaccia che la libreria definisce per comunicare al chiamante, quindi avere entrambe le app chiamanti definiscono le proprie implementazioni di questa interfaccia, la libreria chiama i metodi su questa interfaccia e non conosce nulla della implzione.

Il chiamante elabora i metodi di conseguenza ...

public interface IProgressReporter 
{ 
     void ReportMessage(string message); 
} 



public class WinFormsProgressReporter : IProgressReporter 
{ 
    public void ReportMessage(string message) 
    { 
      MessageBox.SHow(message); 
    } 
} 

public class ConsoleAppProgressReporter : IProgressReporter 
{ 
    public void ReportMessage(string message) 
    { 
      Console.WriteLine(message); 
    } 
} 

public class LibraryClass 
{ 
    public static void SomeMethod(IProgressReporter rep) 
    { 
     rep.ReportMessage("Wooooohooooo!"); 
    } 
} 
0

Questo è dove hai bisogno di una chiara definizione tra il livello di logica e il vostro livello di interfaccia utente. È perfettamente accettabile e normale inserire questo tipo di logica nell'interfaccia utente, poiché quel bit non può ragionevolmente vivere all'interno del livello logico, poiché dipende dall'interfaccia utente.

2

Perché non definire un inteface, IOutputHandler, che ha un metodo denominato DisplayOutput. Ne avresti 2 implementazioni, una per l'app winforms e una per la console. Chiameresti la versione corretta di esso in fase di runtime. È possibile modificare la libreria di classi in modo che disponga di un'istanza di campo privata per IOutputHandler e quindi di inserirne una appropriata in fase di runtime.

+0

Vero: dovrebbe esaminare l'iniezione delle dipendenze e guardare le varie piattaforme esistenti come StructureMap. – MunkiPhD

2

È possibile generare un evento nella libreria di classi che è ascoltato/registrato da qualsiasi livello UI/Console. In questo modo può decidere di agire sull'evento se è ritenuto necessario in tutti i luoghi che desideri. Dipende davvero da come è impostata la tua architettura.

+0

Il gestore di eventi dovrebbe richiamare nella libreria per impostare il risultato di ritorno e prima di continuare è necessario attendere la risposta, ma funzionerebbe – ChrisF

0

La logica dovrebbe mai, mai riferirsi a qualsiasi tipo di componente di interfaccia utente. Se lo fa, è sbagliato, ed è necessario riprogettarlo per rimuovere completamente le dipendenze dell'interfaccia utente.

0

Mentre le risposte dell'interfaccia sono probabilmente soluzioni migliori, se è solo il un metodo, è sufficiente utilizzare un delegato per passare il metodo Console o WinForm alla libreria di classi.

0

Un'altra soluzione

Nella classe lib ..

public void MyLibMethod(Action<string> callBack) 
{ 
     callBack("Yeh baby..."); 
} 

Quindi chiamare

Class.MyLibMethod(s=> Console.WriteLine(s)); 
Problemi correlati