È completamente impossibile avere una separazione totale senza perdite di alcun tipo in un progetto? [chiuso]

3

Per la scorsa settimana ho tentato di scrivere un progetto proof-of-concept usando dependency injection, un livello di servizio, unità di pattern pattern + repository.

Sto cercando di progettare qualcosa che possa essere facilmente utilizzato da qualsiasi tipo di applicazione, sia che si tratti di un'applicazione desktop Windows, un'applicazione CLI, un'applicazione ASP.NET MVC, persino un'applicazione iOS con Mono. Per favore, tieni presente che questo è solo per un proof-of-concept.

Fino ad ora, ho scritto

  • Unità di lavoro + Unità di lavoro fabbrica per NHibernate e Entity Framework (2 framework OR / M per .NET)
  • (generico) repository. Esiste un repository per implementazione OR / M, che considera la rispettiva Unit of Work Factory come parametro costruttore. Ha bisogno di questo per afferrare l'attuale unità di lavoro (dal momento che la sua implementazione contiene le cose necessarie per far funzionare ogni framework OR / M)

Questo ha raggiunto:

  • Posso sostituire le implementazioni del repository e la fabbrica di Unità di lavoro con NHibernate e Entity Framework e funzionerà. Questo è buono, tranne che non ho ancora implementato una vera applicazione, solo unit test.

Questi sono i problemi / sfide che sto affrontando:

  • Ogni tipo di applicazione (desktop, CLI, ASP.NET MVC, iOS, Android, qualsiasi cosa) non definisce un'unità di lavoro allo stesso modo. Un'applicazione desktop (AFAIK) dovrebbe avere una unità di lavoro per schermo - un'applicazione Web dovrebbe avere una unità di lavoro per richiesta, ecc. Non so come condividere una singola unità di lavoro con tutti i repository / servizi ( vedi sotto) che ne ha bisogno. - Michael ha ragione.
  • Voglio che tutta la mia logica risieda in un livello di servizio. Il livello di servizio decide quando deve impegnarsi un'unità di lavoro. L'idea è che chiunque chiami il servizio, sappia cosa passare e sappia cosa aspettarsi come risultato. Se qualcosa va storto, il servizio lo registra. Se dovessi farlo in base alle singole applicazioni, DRY sarebbe stato violato (giusto?).

Sembra che se dovessi implementare questo progetto totalmente separato, la quantità di codice che dovevo riutilizzare non sarebbe tanto quanto la quantità di codice che avrei dovuto scrivere per implementarlo in ogni tipo di applicazione, che, alla fine, molto probabilmente colerebbe il mio contenitore IoC nell'applicazione.

Sono davvero pazzo per aver tentato anche questo?

EDIT: il problema reale che sto affrontando sta fornendo il mio livello di servizio e repository con la stessa istanza di un'unità di lavoro, indipendentemente dal tipo di applicazione utilizzato.

    
posta Jeff 20.05.2013 - 15:43
fonte

3 risposte

4

Each application type (Desktop, CLI, ASP.NET MVC, iOS, Android, whatever) do not define a unit of work the same way. A desktop application (AFAIK) should have a Unit of Work per screen - a Web application should have a Unit of Work per request, etc. I don't know how I would share a single unit of work with all the repositories/services (see below) that needs it.

Per me, sembra che tu stia definendo "un'unità di lavoro" intorno a come viene presentato all'utente, piuttosto che attorno a ciò che ha senso eseguire come una singola operazione. A seconda di quanto vuoi mantenere e di dove, "un'unità di lavoro" non sarà "acquistare un oggetto" (fare un esempio per un'applicazione di e-commerce solo per avere un esempio concreto) - è più come un scenario o caso d'uso - ma forse piuttosto "aggiungi una determinata quantità di prodotto dato al carrello", "ottieni il contenuto del carrello", "imposta l'indirizzo di consegna", "imposta i dettagli del pagamento" e "conferma l'ordine".

Se lo fai in questo modo, puoi facilmente esporre la funzionalità (acquistando qualcosa) in modi che abbiano senso in qualsiasi interfaccia utente con cui stai lavorando. Un'applicazione Web potrebbe visualizzare il contenuto di un carrello acquisti su una pagina e chiedere i dettagli del cliente su un'altra, mentre un'applicazione GUI client potrebbe integrarla in un'unica vista fisica. Naturalmente, ogni applicazione client richiederà ancora la conoscenza di come eseguire le varie operazioni, ma non avrà bisogno di una conoscenza approfondita dell'architettura generale più di quanto sia necessario conoscere ogni dettaglio di implementazione di Win32 per creare applicazioni Windows (oops, cattivo esempio ;.))

    
risposta data 20.05.2013 - 16:20
fonte
0

Sembra che tu stia facendo qualcosa di estremamente statico nei tuoi servizi o qualcosa di molto strano nel client.

Il contesto EF o NHibernate equiv non sarà una cosa facile da mantenere tra le richieste, una volta che si arriva a caricare il bilanciamento e tale diventa quasi impossibile da fare correttamente, così si finisce per passare un token o usando la sessione (che è davvero una ricerca di token in ogni caso) e le istanze non contano tanto perché si finisce con metodi come:

 AddItemToCart(CartID, ItemID) 

che sono semplici Consentitemi di utilizzare i provider e astratto con un gestore / controller / servizio. Anche se passi l'intero oggetto attraverso il servizio, passa attraverso un serializzatore o qualcosa su entrambe le estremità e hai comunque due o più istanze.

    
risposta data 20.05.2013 - 18:15
fonte
0

Sto facendo fatica a capire perché è necessario riutilizzare le unità di lavoro tra le chiamate di servizio. Il caricamento di un carrello è un'unità di lavoro. Il salvataggio delle modifiche in quel carrello è una unità di lavoro separata.

Forse il vero problema è nella tua definizione di ciò che comprende un'unità di lavoro. Ogni volta che chiami un metodo di servizio nell'API dell'applicazione, vale a dire, per definizione, un'unità di lavoro. Se le tue unità di lavoro si interrompono su più chiamate, ciò mi suggerisce che hai una perdita di business logic nel tuo codice UI.

    
risposta data 20.05.2013 - 18:36
fonte

Leggi altre domande sui tag