2010-04-06 17 views
13

Jestem obecnie rozwijających się średniej wielkości aplikacji, która będzie dostępu 2 lub więcej baz danych SQL, w różnych miejscach itd ...Korzystanie z ogólnej Repository wzór z Fluent NHibernate

Zastanawiam użyciu coś podobnego do tego: http://mikehadlow.blogspot.com/2008/03/using-irepository-pattern-with-linq-to.html

jednak chcę użyć fluent NHibernate, zamiast LINQ-SQL (i oczywiście nHibernate.Linq)

Czy to opłacalne?

Jak skonfigurować konfigurację? Gdzie moje definicje mapowania pójdą itp ...?

Ta aplikacja docelowo będzie miała wiele aspektów - od WebUI, biblioteki WCF i aplikacji/usług Windows.

także, na przykład na stole "produkt", by utworzyć klasę "ProductManager", który ma metod takich jak:

GetProduct, GetAllProducts etc ...

Wszelkie wskaźniki są znacznie odbierane.

+7

Tylko wzór: Fluent NHibernate to tylko sposób na skonfigurowanie odwzorowań NHibernate; nie jest to inna struktura i nie ma nic wspólnego z implementacją repozytorium. –

Odpowiedz

22

Moim zdaniem (i według niektórych opinii innych osób) repozytorium powinno być interfejsem, który ukrywa dostęp do danych w interfejsie, który naśladuje interfejs kolekcji. Dlatego repozytorium powinno być IQueryable i 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); 
    } 
} 

Nie wdrożyć do SubmitChanges metody jak w samym repozytorium, ponieważ chcę, aby przedstawić zmiany kilku repozytoriów używanych przez jednego działania użytkownika na raz. I ukryć zarządzanie transakcjami w jednostce interfejsu pracy:

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

używam sesji w określonej jednostce NHibernate realizacji prac jako sesji dla repozytoriów:

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

w rzeczywistej aplikacji, I użyj bardziej skomplikowanego interfejsu repozytorium z metodami takimi jak paginacja, szybkie ładowanie, wzorzec specyfikacji, dostęp do innych sposobów kwerend używanych przez NHiberante zamiast tylko linq. Implementacja linq w bagażniku NHibernate działa wystarczająco dobrze dla większości zapytań, które muszę wykonać.

+0

Genialny! Prosty, IQueryable i jednostka pracy. To naprawdę pasuje do definicji repozytorium "Zbiór obiektów domeny [...]". Dodaj trochę DI i staje się naprawdę użyteczny!Dobra robota - :) – maxbeaudoin

+2

Czy możemy zobaczyć, jak wygląda "bardziej skomplikowany interfejs repozytorium"? Jest to dobre, ale chciałbym również móc "robić strony takie jak paginacja, szybkie ładowanie, wzorzec specyfikacji, dostęp do innych sposobów kwerend używanych przez NHiberante zamiast tylko linq". Przydałabyś się również, gdybyś mógł pokazać, jak go używasz. Dzięki za to! – W3Max

+0

Ciekawi mnie również sposób definiowania IRepository do korzystania z innych metod kwerendy przy pomocy NHibernate - przy zachowaniu ogólnej charakterystyki. –