2012-01-01 12 views
5

Me pregunto cuánto debería saber mi capa de servicio de mi repositorio? En el proyecto anterior, siempre devolvía listas y tenía un método para cada cosa que necesitaba.Patrón de repositorio con NHibernate?

Así que si tuviera que devolver todas las filas que tenían una Id de 5 sería un método. Tengo un repositorio genérico para crear, actualizar, eliminar y otras opciones de NHibernate, pero para consultarlo no lo hago.

Ahora estoy empezando a usar más IQueryable ya que comencé a tener problemas para tener tantos métodos para cada caso.

Digamos que si tuviera que devolver todo lo que tenía una determinada Id y necesitaba 3 tablas que estaban ansiosas de cargar, sería un método nuevo. Si necesitaba una determinada Id y no deseo cargarla, sería un método diferente.

Así que ahora estoy pensando si metodo que hace la parte de la cláusula where y devuelvo IQueryable entonces puedo agregar el resultado (es decir, si tengo que hacer una carga ansiosa).

Al mismo tiempo, ahora esto hace que la capa de servicio esté más al tanto de la capa de repositorio y ya no puedo cambiar el repositorio tan fácil como ahora tengo NHibernate específico en la capa de servicio.

Tampoco estoy seguro de cómo afectaría la burla.

Así que ahora me pregunto si voy por esta ruta si el repositorio es necesario, ya que ahora parece que se han mezclado.

Editar

Si me deshago de mi repositorio y sólo tiene la sesión en mi capa de servicio es un punto que hay que tener una unidad de la clase de trabajo, entonces?

public class UnitOfWork : IUnitOfWork, IDisposable 
    { 
     private ITransaction transaction; 
     private readonly ISession session; 

     public UnitOfWork(ISession session) 
     { 
      this.session = session; 
      session.FlushMode = FlushMode.Auto; 
     } 

     /// <summary> 
     /// Starts a transaction with the database. Uses IsolationLevel.ReadCommitted 
     /// </summary> 
     public void BeginTransaction() 
     { 
      transaction = session.BeginTransaction(IsolationLevel.ReadCommitted); 
     } 

     /// <summary> 
     /// starts a transaction with the database. 
     /// </summary> 
     /// <param name="level">IsolationLevel the transaction should run in.</param> 
     public void BeginTransaction(IsolationLevel level) 
     { 
      transaction = session.BeginTransaction(level); 
     } 

     private bool IsTransactionActive() 
     { 
      return transaction.IsActive; 
     } 

     /// <summary> 
     /// Commits the transaction and writes to the database. 
     /// </summary> 
     public void Commit() 
     { 
      // make sure a transaction was started before we try to commit. 
      if (!IsTransactionActive()) 
      { 
       throw new InvalidOperationException("Oops! We don't have an active transaction. Did a rollback occur before this commit was triggered: " 
                  + transaction.WasRolledBack + " did a commit happen before this commit: " + transaction.WasCommitted); 
      } 

      transaction.Commit(); 
     } 

     /// <summary> 
     /// Rollback any writes to the databases. 
     /// </summary> 
     public void Rollback() 
     { 
      if (IsTransactionActive()) 
      { 
       transaction.Rollback(); 
      } 
     } 

     public void Dispose() // don't know where to call this to see if it will solve my problem 
     { 
      if (session.IsOpen) 
      { 
       session.Close(); 
      } 

     } 

Respuesta

4

Todo el mundo tiene una opinión sobre cómo usar el repositorio, qué abstraer, etc. Ayende Rahien tiene pocas publicaciones buenas sobre el tema: Architecting in the pit of doom: The evils of the repository abstraction layer y Repository is the new Singleton. Esos son algunos de los motivos por los que no deberías tratar de crear otra abstracción además de la ISession de NHibernate.

+0

Voy a buscar más en él. Lo que me atrapa es que me gusta la idea de que la capa de servicio no sepa nada sobre la base de datos, lo que facilita la prueba unitaria (si es que alguna vez lo necesito) y es fácil cambiar los ORM. ¿cómo manejas estos escenarios? – chobo2

+0

También me pregunto si me deshago de los repositorios ¿hay algún punto en mi unidad de trabajo entonces? Vea Editar – chobo2

+0

Puede usar UnitOfWork solo para envolver la sesión, o incluso usar la sesión NH directamente. En cuanto a las pruebas unitarias, puede usar una base de datos en memoria para pruebas unitarias ** con ** NHiberate. Aquí hay una publicación al respecto de Ayende: http://ayende.com/blog/3983/nhibernate-unit-testing –

2

Lo que pasa con NHibernate es que le da más si no intenta abstraerlo. Hacer que su capa de servicio dependa de NHibernate no es necesariamente algo malo. Le da control sobre las sesiones, el almacenamiento en caché y otras funciones de NHibernate, y le permite mejorar el rendimiento, sin mencionar el ahorro de todo el código de envoltura redundante que ha mencionado.

+1

Agregando a esta respuesta: La sesión NHibernate es la UnitOfWork – ivowiblo

+1

Es por eso que me pregunto si hay un punto para la clase UnitOfWork que hice si no estoy usando el patrón de repositorio? – chobo2

Cuestiones relacionadas