2011-07-22 672 views
22

¿Cuál es el enfoque recomendado para tomar con el patrón Nhibernate + Repository?NHibernate and Repository pattern

Hay tantos artículos y opiniones diferentes en torno a que no estoy seguro de qué camino tomar. Take this lengthy article, por ejemplo. Da un ejemplo de objetos Query, pero cada repositorio concreto acepta un ISession en su constructor. ¿Qué debería preocuparme por las sesiones de NH en mi BL (capa de negocios)?

  1. Crear un montón de repositorios, cada uno de ellos con un montón de métodos específicos?
    Al parecer, eso es demasiado trabajo porque BL está "permitido" ser consciente de NHibernate (Repository is the new Singleton)?

  2. Crear un único repositorio genérico, pero exponer IQueriable<T> y utilizar LINQ en BL
    De vez en cuando hay una consulta que LINQ to NHibernate no será capaz de procesar (o tengo que pellizcar el SQL manualmente una vez en cien consultas). Esto es fácil con métodos de repo personalizados, pero casi imposible con código que depende de LINQ. Y usar ambos solo porque LINQ se rompe en algunos casos es una tontería.

  3. objetos de consulta?
    QueryOver también es específico de NH, lo que significa que BL está nuevamente al tanto de la implementación de DAL.

  4. otro enfoque?

Obviamente, tengo que ser capaz de gestionar transacciones en algún lugar, tal vez usando un Patten de unidad de trabajo (aunque también existen muchas implementaciones diferentes de que alrededor).

+0

¿Estás hablando de repositorio como en DDD? – mathieu

+0

@mathieu: sí. (No estoy seguro de en qué otros repositorios podría pensar). Pero en general, estoy buscando una forma recomendada de organizar una aplicación escrita en 2011, con todas las herramientas y patrones modernos. He usado NHibernate de varias maneras antes, pero odio cuando necesito hacer referencia a clases específicas de NH en mi BL. Y parece que cada vez es más común decir que NH no necesita abstracción. – doe

+0

@doe - seguramente sus clases específicas de NH son simplemente las entidades de su dominio? de lo contrario, está buscando cantidades considerables de duplicación de propiedades y mapeo. –

Respuesta

13

Existen muchas opiniones contradictorias en el mundo de la arquitectura de software y muchas de ellas están muy bien fundadas.

1) Sí, la definición de un repositorio para cada raíz agregada puede ser exagerada, pero es posible que la forma en que recupere los datos para esa raíz sea específica y que desee controlarla en un repositorio personalizado . El artículo de Ayende es muy elocuente e impacta mucho en el deseo típico del desarrollador de soluciones "sobre arquitectónicas", a menudo en detrimento de la funcionalidad.

2) El uso de LINQ con NHibernate es una opción, pero quiero subrayar que usted debe darse la posibilidad de recurrir a la utilización de criterios de consulta o HQL si usted hace esto. En esa etapa puede que se encuentre poniendo tantas excepciones que se preguntará cuál fue el punto inicial de la abstracción.

3) QueryOver es un envoltorio de tipo seguro alrededor de consultas de criterios y sólo esto los hace mucho más atractivo para mí. A menudo me encuentro retrocediendo a los criterios para el control total que ofrecen, la alternativa a menudo es que tengo que usar "cuerdas mágicas". Esto esencialmente haría NHibernate su abstracción de acceso a datos. De hecho, sería una mejor abstracción que la mayoría de los 'repositorios' porque la mayoría de ellos solo proporcionan métodos CRUD ... un repositorio debería ser capaz de manejar las especificaciones de la consulta (exactamente cómo funciona QueryOver).

En lo que respecta a las transacciones, depende de su marco de trabajo.En realidad, no creo que sea realista o beneficioso utilizar el patrón de unidad de trabajo en una aplicación y esconder su implementación (se puede resumir, pero ¿de qué sirve?) ¿Realmente va a cambiar su ORM?)

Si está utilizando ASP.NET, simplemente (como mínimo) inicie la transacción al inicio de la solicitud, restituya las excepciones y confirme al final.

Si está utilizando WinForms, es posible que deba considerar la duración de cada tarea de UI como su unidad de trabajo.

+0

En el momento del comentario que 1337 medallas :) 6,907 s13 b37 Tengo miedo de +1 porque podría echar a perder el efecto – Shagglez

2

El sitio parece estar abajo ahora, pero me gusta mucho el enfoque de Bob Craven y lo han utilizado en algunos grandes proyectos:

http://blog.bobcravens.com/2010/06/the-repository-pattern-with-linq-to-fluent-nhibernate-and-mysql/ EDIT: Google cache version of the link

Se utiliza genéricos y un patrón UOW para acceso a datos .

Sí, es un poco doloroso cuando necesita recurrir a SQL, pero utilizo una capa de servicio de datos que puede abstraer eso. Es decir. La capa de servicio de datos usa los datos genéricos siempre que sea posible (90% del tiempo) y usa el lenguaje SQL/otros marcos en otros lugares.