Использование шаблона общего репозитория с беглым nHibernate - PullRequest
13 голосов
/ 07 апреля 2010

В настоящее время я разрабатываю приложение среднего размера, которое будет иметь доступ к 2 или более базам данных SQL на разных сайтах и ​​т. Д.

Я собираюсь использовать что-то похожее на это: http://mikehadlow.blogspot.com/2008/03/using-irepository-pattern-with-linq-to.html

Однако я хочу использовать свободный nHibernate вместо Linq-to-SQL (и, конечно, nHibernate.Linq)

Это жизнеспособно?

Как мне настроить это? Куда пошли бы мои определения картографирования и т. Д.? *

Это приложение в конечном итоге будет иметь множество аспектов - от WebUI, библиотеки WCF и приложений / служб Windows.

Также, например, в таблице «product» я бы создал класс «ProductManager», который имеет такие методы:

GetProduct, GetAllProducts и т. Д. *

Любые указатели в значительной степени принимаются.

Ответы [ 2 ]

22 голосов
/ 07 апреля 2010

По моему мнению (и, по мнению некоторых других людей), хранилище должно быть интерфейсом, который скрывает доступ к данным в интерфейсе, который имитирует интерфейс коллекции.Вот почему репозиторий должен быть IQueryable и 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);
  }   
}

Я не реализую метод, подобный SubmitChanges, в самом репозитории, потому что я хочу отправить изменения нескольких репозиториев, используемых одним действием пользователя одновременно.Я скрываю управление транзакциями в интерфейсе единицы работы:

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

Я использую сеанс реализации конкретной единицы работы NHibernate в качестве сеанса для хранилищ:

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

ВВ реальном приложении я использую более сложный интерфейс репозитория с такими методами, как разбиение на страницы, загрузка, шаблон спецификаций, доступ к другим способам запросов, используемым NHiberante, а не просто linq.Реализация linq в транке NHibernate работает достаточно хорошо для большинства запросов, которые мне нужно сделать.

1 голос
/ 07 апреля 2010

Вот мои мысли о родовых репозиториях:

Преимущество создания общего хранилища по сравнению с конкретным хранилищем для каждого объекта?

Я успешно использовал этот шаблон с NHibernate и не нашел никаких реальных недостатков.

Суть в том, что действительно универсальные репозитории представляют собой нечто вроде красной сельди, но те же преимущества можно получить, если взглянуть на проблему несколько иначе.

Надеюсь, это поможет.

...