Por que eu iria usar a Unidade de padrão de trabalho em cima de uma sessão NHibernate?

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

  •  13-09-2019
  •  | 
  •  

Pergunta

Quando eu ia escrever uma implementação uow em cima do que já é fornecido pelo NHibernate? exemplos Qualquer mundo real?

Foi útil?

Solução

A unidade de trabalho que você está descrevendo já é fornecido pelo NHibernate por isso não há razão para fazer tal unidade de trabalho.

O que temos em nosso Serviço WCF é uma unidade maior nível de trabalho que contém informações importantes em nossa aplicação para a unidade de trabalho atual. Isso inclui a abstrair o NHibernate ISession para nós. Quando você decompô-lo você tem o código que se encaixa em três categorias

  1. código que precisa lidar com uma unidade de trabalho. Não importa quem faz a unidade de trabalho. Poderia ser NHibernate, iBatis ou um ORM personalizada. Todas as necessidades de código para fazer é carregar, reversão, Save, etc. Não nem deve se preocupam com o mecanismo usado para fazê-lo.

  2. código que precisa lidar com um ISession diretamente porque ele está fazendo NHibernate coisas específicas. Geralmente isso tem a ver com consultas complexas que precisam ser criadas.

  3. não precisa saber que ele está sendo executado em uma unidade de trabalho ou acesso a ISession. Nós podemos ignorar completamente este como parte desta discussão.

Enquanto o código em 1. poderia apenas trabalho contra um ISession nossa preferência é tentar abstratas coisas de distância no código que não podemos controlar, direta ou isso pode mudar. Isso tem valor para duas razões.

  • Quando começamos não estávamos 100% vendido em NHibernate. Nós estávamos considerando iBatis ou algo personalizado. Obviamente, isso não é mais um problema.

  • A equipe inteira não são especialistas em NHibernate nem queremos que eles sejam. Para a maior parte das pessoas escrever código que se encaixa na categoria 1. e tudo o que sabem sobre a nossa unidade de trabalho. Quando o código na categoria 2. tem que se escreveu ele fica escrito por as pessoas na equipe que entender bem NHibernate.

Assim, para fechar, eu diria que o tipo de unidade de trabalho que você está falando não é necessário que eu gostaria de sugerir que um maior nível Unidade de Trabalho pode fornecer um monte de valor.

Outras dicas

Meu unidade básica de interface de trabalho contém os seguintes métodos - Inicializar - Comprometer - reversão - IDisposable.Dispose

Eu usá-lo tanto para sessão e gerenciamento de transações. É útil, porque eu não tenho que escrever esse código novo e de novo para diferentes escopos de sessão. (Unidade de trabalho por solicitação, por série de pedidos, por fio, etc)

Desde que você configurar todos os seus mapeamentos corretamente (ou seja, cascatas), você não tem que fazer qualquer coisa e especial ISession vai fazer muito bem. No entanto, se você estiver escrevendo um aplicativo de 3 camadas, você terá a operações de banco de dados seqüência manualmente você deseja ser realizado em uma única transação. "Implementação de referência" de Fowler em "Patterns of Enterprise Application Architecture" pode ser um bom ponto de partida:

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());
   }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top