2010-05-01 9 views
23

Existen varias preguntas similares sobre este tema, ya que todavía no he encontrado motivos suficientes para decidir qué camino tomar.NHibernate con o sin Repositorio

La verdadera pregunta es, ¿es razonable abstract the NHibernate using a Repository pattern o not?

Parece que la única razón detrás de la abstracción es dejar una opción para reemplazar NHibernate con un ORM diferente si es necesario. Pero crear repositorios y abstraer consultas parece agregar otra capa y hacer gran parte de la instalación de fontanería a mano.

Una opción es usar exponer IQueryable<T> en la capa empresarial y usar LINQ, pero por mi experiencia el soporte de LINQ aún no está completamente implementado en NHibernate (las consultas simplemente no siempre funcionan como se esperaba y odio pasar tiempo en la depuración Un marco).

Aunque hacer referencia a NHibernate en mi capa empresarial me duele, se supone que es una abstracción del acceso a los datos por sí solo, ¿no?

¿Qué opina sobre esto?

+0

¿Cómo agregar un nuevo elemento a la base de datos con solo linq? – Paco

+0

@Paco: Agregar un nuevo elemento a la base de datos es bastante fácil de resumir, no estoy hablando de eso. La consulta es el problema real, ya que no hay una forma simple de habilitar consultas complejas a través de un repositorio sin codificación suficiente. – Groo

Respuesta

5

Buenas suspensiones. También estaba pensando en ellos hace unos días.

En realidad, pruebe NHibernate 3.0 alpha (o el tronco actual), su nuevo proveedor de LINQ es mucho mayor que los anteriores. (Hasta ahora solo encontré un método que no funciona, pero es posible enganchar su propio mecanismo si se encuentra con algo que no admite de manera predeterminada.) No tuve problemas (todavía?) Con el uso de la corriente el maletero. Puede encontrar una compilación "nocturna" en el sitio http://www.hornget.net/packages/, junto con una compilación FluentNHibernate. Fluent realmente aumenta su productividad si sabe cómo usarlo. La comunidad SO really helped me with that, también.

Si está de acuerdo con que su capa de negocio tenga una dependencia directa de NHibernate, o si está escribiendo una aplicación más pequeña que puede mantenerse sin este tipo de abstracción, puede continuar sin el patrón de repositorio. Sin embargo, si lo haces bien, puede ahorrarte una gran cantidad de codificación redundante.

La razón para abstraerlo no solo es útil porque luego puede reemplazar NHibernate más adelante con otro ORM, pero es una buena práctica debido a un concepto llamado Separation of Concerns. Su capa de lógica de negocios no debería importar ni saber nada sobre cómo acceder a los datos con los que trabaja. Esto facilita el mantenimiento de la aplicación o sus diferentes capas, lo que también facilita el trabajo en equipo: si X crea la capa de acceso a los datos y Y escribe la lógica de negocios, no tienen que conocer el trabajo de los demás en detalle.

Exponer un IQueryable<T> es una muy buena idea, y eso es exactamente lo que están haciendo muchas implementaciones de repositorio en este momento. (Y a mí también, aunque preferí escribirlo en una clase estática.) Y, por supuesto, deberá exponer algunos métodos para insertar o actualizar una entidad, o métodos para comenzar y comprometer transacciones, si así lo desea. (The BeginTransaction solo debe devolver un IDisposable para evitar filtrar una interfaz de NHibernate, y eso estará bien.)

Puedo darle algunas instrucciones: revise las implementaciones de SharpArchitecture o FubuMVC Contrib para obtener algunas ideas sobre cómo hacerlo es correcto, y esto es how I solved it.

+0

Gracias por la respuesta. En realidad, lo que quería decir es que usar HNibernate para consultar datos directamente no debería exponer significativamente la implementación de la base de datos a la capa de negocios, una vez que se mapean estos dos modelos. Creo que esa fue la idea original detrás del concepto de ORM. Personalmente, la verdad es que no quiero usarlo directamente, pero un patrón de repositorio (si no expongo IQueryable) requiere codificación adicional. Usar Linq sería encantador, si fuera confiable. Tal vez voy a probar la versión alfa :). – Groo

+0

No tuve problemas (todavía?) Con el uso del tronco actual. Actualizado mi respuesta. – Venemo

1

¡Simplemente diría un gran SÍ! tener un patrón de repositorio, ¡mantener las cosas abstractas!

1

Personalmente prefiero seguir abstrayendo el NHibernate en un patrón de repositorio. La razón es que todavía podría tener otras implementaciones del repositorio para el almacenamiento en caché, burlas para pruebas de unidades, etc. Y también uso IQueryable con mi repositorio, aunque hago que IRepository extienda IQueryable en lugar de exponer una propiedad en IRepository de tipo IQueryable.

Otro punto de repositorio. Algunas personas sugieren no hacerlo genérico y tener la identificación del tipo en el nivel de método (es decir, repositorio.Carrar). Sin embargo, esto supone que habrá un único repositorio que sepa cómo tratar con todos los tipos. No soy un gran admirador de esta noción de un único depósito monolítico. ¿Qué sucede si tiene varias bases de datos? O mecanismos de persistencia múltiple? O algunos tipos de datos permanecen bastante estáticos y pueden almacenarse en caché, pero otros no. Es por eso que me gusta una instancia de repositorio independiente para cada tipo.

Cuestiones relacionadas