Perché utilizzare l'unità di modello di lavoro in cima ad una sessione di NHibernate?

StackOverflow https://stackoverflow.com/questions/980584

  •  13-09-2019
  •  | 
  •  

Domanda

Quando avrei scritto un'implementazione UoW in cima a ciò che è già fornita da NHibernate? Eventuali esempi reali?

È stato utile?

Soluzione

L'unità di lavoro che si sta descrivendo è già fornita da NHibernate quindi non c'è alcun motivo per fare un'unità di lavoro.

Quello che abbiamo in nostro servizio WCF è un'unità più alto livello di lavoro che contiene informazioni importanti nella nostra applicazione per l'unità corrente del lavoro. Questo include l'astrazione NHibernate ISession per noi. Quando si interrompe il basso si dispone di codice che si inserisce in tre categorie

  1. Il codice che deve affrontare un'unità di lavoro. Non importa che sostiene l'unità di lavoro. Potrebbe essere NHibernate, iBatis o un ORM personalizzato. Tutto il codice deve fare è Load, rollback, Save, ecc non né deve preoccuparsi il meccanismo utilizzato per farlo.

  2. Il codice che deve affrontare un ISession direttamente perché sta facendo NHibernate cose specifiche. Di solito questo ha a che fare con le query complesse che devono essere creati.

  3. non ha bisogno di sapere che è in esecuzione in un'unità di lavoro o accedere al ISession. Siamo in grado di ignorare completamente questo come parte di questa discussione.

Mentre il codice a 1. potrebbe solo lavorare contro un ISession la nostra preferenza è quella di cercare di cose astratte via nel codice che noi non controlliamo direttamente o che potrebbero cambiare. Questo ha un valore per due motivi.

  • Quando abbiamo iniziato eravamo non al 100% venduto su NHibernate. Eravamo considerando iBatis o qualcosa di personalizzato. Ovviamente questo non è più un problema.

  • L'intera squadra non sono esperti in NHibernate né vogliamo che siano. Per la maggior parte delle persone la parte di scrittura di codice che si inserisce nella categoria 1. e tutto quello che sanno circa è la nostra unità di lavoro. Quando il codice nella categoria 2. deve ottenere scritto viene scritto da gente sulla squadra che capire bene NHibernate.

Quindi, per chiudere vorrei dire che il tipo di unità di lavoro si sta parlando non è necessario vorrei suggerire che un'unità più elevato livello di lavoro in grado di fornire un sacco di valore.

Altri suggerimenti

La mia unità di base dell'interfaccia lavoro contiene i seguenti metodi - Inizializzare - Commettere - Ripristino - IDisposable.Dispose

Io lo uso sia per la sessione e la gestione delle transazioni. E 'utile perché non devo scrivere che il codice ancora e ancora per diversi ambiti di sessione. (Unità di lavoro per ogni richiesta, per ogni serie di richieste, per thread, ecc)

A condizione di impostare tutte le mappature correttamente (cioè cascate), non c'è bisogno di fare nulla di speciale e ISession farà bene. Tuttavia, se si sta scrivendo un'applicazione a 3 livelli, dovrete manualmente le operazioni del database di sequenza che si desidera essere eseguita in una singola transazione. "Implementazione di riferimento" di Fowler in "Modelli di Enterprise Application Architecture" può essere un buon punto di partenza:

class UnitOfWork... 

   public void registerNew(DomainObject obj) {
      Assert.notNull("id not null", obj.getId());
      Assert.isTrue("object not dirty", !dirtyObjects.contains(obj));
      Assert.isTrue("object not removed", !removedObjects.contains(obj));
      Assert.isTrue("object not already registered new", !newObjects.contains(obj));
      newObjects.add(obj);
   }
   public void registerDirty(DomainObject obj) {
      Assert.notNull("id not null", obj.getId());
      Assert.isTrue("object not removed", !removedObjects.contains(obj));
      if (!dirtyObjects.contains(obj) && !newObjects.contains(obj)) {
         dirtyObjects.add(obj);
      }
   }
   public void registerRemoved(DomainObject obj) {
      Assert.notNull("id not null", obj.getId());
      if (newObjects.remove(obj)) return;
      dirtyObjects.remove(obj);
      if (!removedObjects.contains(obj)) {
         removedObjects.add(obj);
      }
   }
   public void registerClean(DomainObject obj) {
      Assert.notNull("id not null", obj.getId());
   }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top