In un programma module-core, come devono interagire i moduli l'uno con l'altro?

2

Breve background: sto usando MEF / C # per lo sviluppo di un programma che ha un core (singleton) e più parti MEF (io li chiamo moduli, ogni modulo è un assembly separato con una classe che contiene l'esportazione MEF). Il core importa tutte le parti che sono necessarie / disponibili e le inizializza (fa sì che leggano i loro file di configurazione, quella roba avviene nei costruttori, come al solito)

Ora, il mio problema è che ho bisogno di moduli per interagire tra loro (ad esempio, il modulo A, un'interfaccia grafica utente, ha bisogno di ottenere alcuni dati da un database, dovrebbe in qualche modo chiamare una funzione sul modulo del database (modulo B).)

Come ho fatto? Certo, potrei rendere pubbliche quelle parti / moduli nel mio nucleo, aggiungere un riferimento al nucleo del mio modulo e farcela, ma in qualche modo, mi sentiresti brutto / cattivo. (principalmente perché ho dei problemi di sicurezza su un'implementazione del genere, tutti potrebbero semplicemente chiamare quella funzione, a meno che non utilizzi qualcosa come questo , ma ancora non sembra giusto.

Un altro approccio sarebbe quello di mettere tutte queste funzioni nel nucleo, dove chiamano semplicemente la funzione corrispondente del modulo. Anche questo mi fa male perché dovrei aggiungere un sacco di cose al mio nucleo e in alcuni casi sarebbe qualcosa che un potenziale cliente non userà mai perché non ha bisogno / ha il modulo specifico.

Qualcuno conosce un metodo migliore per farlo? Forse la mia linea di pensiero è andata completamente storta da qualche parte?

    
posta Steffen Winkler 24.04.2013 - 09:25
fonte

3 risposte

4

module A, a graphical user interface, needs to get some data from a database

Questo è indicativo di un design del modulo errato.

Il punto di divisione del codice in moduli è la compartimentalizzazione della funzionalità. Ciò significa che ogni modulo dovrebbe avere un'area specifica di funzionalità e farlo solo.

Un modulo GUI dovrebbe solo gestire l'interfaccia utente.

Un modulo di database dovrebbe solo interagire con il database.

Il passaggio di informazioni da una all'altra dovrebbe avvenire a un livello più alto. Questo potrebbe essere il tuo modulo principale. Oppure, a seconda di cosa stai cercando di fare, potrebbe essere sensato aggiungere un altro livello.

Esempio:

Se l'utente fa clic su un pulsante "Ottieni i miei dati", un gestore di eventi nel modulo GUI richiama un metodo principale che richiede i dati. Questo metodo core chiama quindi il modulo del database per ottenere i dati.

    
risposta data 24.04.2013 - 09:49
fonte
2

Perché avere un nucleo?

Voglio dire se tutto è composto da moduli, cosa fa il nucleo? Perché i tuoi moduli non si riferiscono tra loro (tramite interfacce) e quindi utilizzano MEF per attivare implementazioni concrete?

Quindi se alcuni componenti dell'interfaccia utente devono accedere ad un qualche repository di dati, lo richiede tramite Import mentre ignora il resto del modulo, oltre all'implementazione fornita. I componenti dei tuoi moduli possono quindi funzionare l'uno con l'altro (e / o varianti simulate). Basta fare attenzione a utilizzare interfacce snelle e non impazzire con le responsabilità e dovrebbe funzionare bene.

    
risposta data 24.04.2013 - 13:37
fonte
0

Parliamo di responsabilità.

La GUI

  • gestisce l'input dell'utente
  • richiesta dati
  • riceve i dati richiesti
  • valorizza / mostra dati

Il livello di accesso ai DB

  • database delle query
  • elaborare i dati interrogati
  • restituisce i dati elaborati

Ulteriori responsabilità

  • esamina le richieste di dati per verificare che non siano dannosi. Richiesta di sicurezza AKA per la sicurezza.

Ci sono due opzioni di base nel tuo caso per chi (che area) gestirà le ulteriori responsabilità.

  1. La GUI gestisce le responsabilità di lavaggio. Ciò mantiene pulito il tuo livello DB a rischio di confondere il tuo codice GUI. Inoltre, inserisce fiducia nel codice GUI che potrebbe non essere appropriato.

  2. Il livello DBA gestisce le responsabilità di lavaggio. Questo risolve i problemi di fiducia ma potenzialmente confonde il codice del livello DBA.

In alternativa, prendi in considerazione la creazione di un livello aggiuntivo la cui responsabilità è quella di eliminare le richieste di dati in arrivo. Per facilitare la revisione della sicurezza, vorrei incoraggiare la creazione di uno specifico oggetto data request che contiene gli elementi chiave su cui si sta interrogando (ID utente, numeri di ordinazione, intervalli di date, codici di stato, ecc ...).

Questo livello di astrazione ti offre un paio di notevoli vantaggi.

  • La GUI non si preoccupa più della formattazione di oggetti per un facile utilizzo da parte del livello DBA.
  • Il livello di scrubbing ha uno scopo preciso e il codice di sicurezza / convalida si trova all'interno della stessa area.
  • Il livello DBA può essere collegato al livello di scrubbing e attivare i controlli di sicurezza su data request prima di operare sulla richiesta.
  • Le future modifiche alla GUI e al livello DBA sono facilitate dal momento che ora hai un contratto in essere. Il flusso di dati è simile a: GUI <=> AR <=> DBA . Le modifiche future devono essere convalidate solo per la metà del contratto anziché per l'intero contratto.

Fortunatamente, un bel po 'di gente ha già lavorato a questa sfida in passato. Il pattern MVVM ref 1 , ref 2 , ref 3 vale la pena leggere per la panoramica e le idee sull'astrazione anche se non si sceglie di utilizzare l'intero schema. Potrebbe essere più pesante da implementare rispetto a ciò che desideri. MEF si adatta bene a questo modello, AFAIK. Suggerimento per i professionisti: l'ultimo riferimento è la guida per gli sviluppatori di MS su prism ed è un vero e proprio tesoro di informazioni per l'area in cui lavori.

    
risposta data 24.04.2013 - 13:29
fonte

Leggi altre domande sui tag