2010-04-06 9 views
13

Attualmente sto sviluppando un'applicazione di medie dimensioni, che accederà 2 o più database SQL, su diversi siti ecc ...Utilizzando un modello di repository generico con fluente NHibernate

Io sto considerando se usare qualcosa di simile a questo: http://mikehadlow.blogspot.com/2008/03/using-irepository-pattern-with-linq-to.html

Tuttavia, voglio usare fluente NHibernate, al posto di LINQ to SQL (e naturalmente nHibernate.Linq)

è questo fattibile?

Come dovrei procedere per la configurazione di questo? Dove dovrebbero andare le mie definizioni di mappatura, ecc ...?

Questa applicazione alla fine avrà molte sfaccettature - da una WebUI, da una libreria WCF e da applicazioni/servizi Windows.

anche, per esempio su un tavolo "prodotto", dovrei creare una classe "product manager", che ha metodi come:

EsprProdotto, GetAllProducts ecc ...

Tutti gli indicatori sono molto ricevuti.

+7

Solo un sidenote: Fluent NHibernate è solo un modo per configurare i mapping di NHibernate; non è un framework diverso e non ha nulla a che fare con l'implementazione del repository. –

risposta

22

Secondo me (e anche in alcuni altri popoli) un repository dovrebbe essere un'interfaccia che nasconde l'accesso ai dati in un'interfaccia che imita un'interfaccia di raccolta. Ecco perché un repository dovrebbe essere 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); 
    } 
} 

Non implementare un SubmitChanges come metodo nel repository per sé, perché voglio inviare le modifiche dei diversi repository utilizzati da un'azione dell'utente in una sola volta. Nascondo la gestione delle transazioni in un'unità di interfaccia di lavoro:

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

io uso la sessione di un'unità specifica NHibernate di realizzazione lavoro come sessione per i repository:

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

In un'applicazione reale, io utilizzare un'interfaccia repository più complicata con metodi per impaginazione, caricamento impaziente, modello di specifica, accesso agli altri modi di interrogazione utilizzati da NHiberante invece di solo linq. L'implementazione di linq nel trunk di NHibernate funziona abbastanza bene per la maggior parte delle query che devo fare.

+0

Brillante! Semplice, IQueryable e un'unità di lavoro. Questo si adatta perfettamente al modello di repository "Definizione di oggetti in memoria [...]". Aggiungi qualche DI e diventa davvero utilizzabile!Buon lavoro - :) – maxbeaudoin

+2

Possiamo vedere come appare "un'interfaccia repository più complicata"? Questo è buono ma vorrei anche essere in grado di fare "cose ​​come impaginazione, caricamento impaziente, schema delle specifiche, accesso agli altri modi di interrogare usati da NHiberante invece di solo linq". Inoltre, sarebbe utile se potessi dimostrare come lo stai usando. Grazie in anticipo! – W3Max

+0

Sono curioso di sapere come si sta definendo l'IRepository per sfruttare gli altri metodi di query con NHibernate, pur mantenendo generico. –

1

Qui sono i miei pensieri su repository generici:

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

Ho usato con successo quel modello con NHibernate, e non hanno trovato alcuna reali carenze.

L'essenza è che i depositi veramente generici sono un po 'una falsa pista, ma gli stessi benefici possono essere realizzati pensando al problema in modo leggermente diverso.

Spero che questo aiuti.

Problemi correlati