2010-04-06 9 views
13

Estoy desarrollando actualmente una aplicación de tamaño mediano, que accederá a 2 o más bases de datos SQL, en diferentes sitios, etc ...El uso de un patrón de repositorio genérico con fluidez NHibernate

Estoy considerando el uso de algo similar a esto: http://mikehadlow.blogspot.com/2008/03/using-irepository-pattern-with-linq-to.html

Sin embargo, quiero usar fluidez NHibernate, en lugar de LINQ to SQL (y por supuesto nHibernate.Linq)

Es esto viable?

¿Cómo hago para configurar esto? ¿Dónde irían mis definiciones de mapeo, etc.?

Esta aplicación eventualmente tendrá muchas facetas - de un WebUI, aplicaciones WCF Biblioteca y Windows/servicios.

También, por ejemplo en una mesa de "producto", iba a crear una clase "ProductManager", que cuenta con métodos como:

obtenerProducto, GetAllProducts etc ...

Cualquier indicador se reciben en gran medida.

+7

Sólo una nota al margen: Fluido NHibernate es simplemente una manera de configurar asignaciones de NHibernate; no es un marco diferente y no tiene nada que ver con la implementación del repositorio. –

Respuesta

22

En mi opinión (y en alguna opinión de otras personas también), un repositorio debe ser una interfaz que esconde acceso a datos en una interfaz que imita una interfaz de colección. Es por eso que un repositorio debe ser un IQueryable e IEnumerable.

public interface IRepository<T> : IQueryable<T> 
{ 
    void Add(T entity); 
    T Get(Guid id); 
    void Remove(T entity); 
} 

public class Repository<T> : IQueryable<T> 
{ 
    private readonly ISession session; 

    public Repository(ISession session) 
    { 
    session = session; 
    } 

    public Type ElementType 
    { 
    get { return session.Query<T>().ElementType; } 
    } 

    public Expression Expression 
    { 
    get { return session.Query<T>().Expression; } 
    } 

    public IQueryProvider Provider 
    { 
    get { return session.Query<T>().Provider; } 
    } 

    public void Add(T entity) 
    { 
    session.Save(entity); 
    } 

    public T Get(Guid id) 
    { 
    return session.Get<T>(id); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
    return this.GetEnumerator(); 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
    return session.Query<T>().GetEnumerator(); 
    } 

    public void Remove(T entity) 
    { 
    session.Delete(entity); 
    } 
} 

no implementar un método SubmitChanges como en el propio repositorio, porque quiero enviar los cambios de varios repositorios utilizados por una acción del usuario a la vez. Me escondo la gestión de transacciones en una unidad de interfaz de trabajo:

public interface IUnitOfWork : IDisposable 
{ 
    void Commit(); 
    void RollBack(); 
} 

utilizo la sesión de una unidad específica NHibernate de ejecución de los trabajos como de sesión para los repositorios:

public interface INHiberanteUnitOfWork : IUnitOfWork 
{ 
    ISession Session { get; } 
} 

En una aplicación real, utilice una interfaz de repositorio más complicada con métodos para cosas como paginación, carga ansiosa, patrón de especificación, acceso a las otras formas de consulta utilizadas por NHiberante en lugar de solo linq. La implementación de linq en el enlace de NHibernate funciona lo suficientemente bien para la mayoría de las consultas que necesito hacer.

+0

Brillante! Simple, IQueryable y una unidad de trabajo. Eso realmente se adapta a la definición del patrón de depósito "Colección de objetos de dominio en memoria". ¡Agregue DI y se vuelve realmente utilizable!Buen trabajo - :) – maxbeaudoin

+2

¿Podemos ver cómo se ve una "interfaz de repositorio más complicada"? Esto es bueno, pero también me gustaría poder hacer "cosas como la paginación, la carga ansiosa, el patrón de especificación, el acceso a las otras formas de consulta utilizadas por NHiberante en lugar de simplemente linq". Además, sería útil si pudieras demostrar cómo lo estás usando. ¡Gracias de antemano! – W3Max

+0

Tengo curiosidad por saber cómo está definiendo el IRepository para aprovechar los otros métodos de consulta con NHibernate, al tiempo que lo mantiene genérico. –

1

Aquí están mis pensamientos sobre repositorios genéricos:

Advantage of creating a generic repository vs. specific repository for each object?

que han utilizado con éxito ese patrón con NHibernate, y no han encontrado ningún deficiencias reales.

Lo esencial es que los repositorios verdaderamente genéricos son un poco de una pista falsa, pero los mismos se pueden obtener beneficios por pensar en el problema de forma ligeramente diferente.

Espero que ayude.

Cuestiones relacionadas