Я в настоящее время разрабатываю приложение среднего размера, которое получит доступ к 2 или больше базам данных SQL на различных сайтах и т.д...
Я рассматриваю использование чего-то подобного этому: http://mikehadlow.blogspot.com/2008/03/using-irepository-pattern-with-linq-to.html
Однако я хочу использовать быстрый nHibernate вместо Linq-SQL (и конечно nHibernate. Linq)
Действительно ли это жизнеспособно?
Как я пошел бы о конфигурировании этого? Куда мои определения отображения пошли бы и т.д....?
Это приложение будет в конечном счете иметь много фасетов - от WebUI, Библиотеки WCF и Приложений Windows / сервисы.
Кроме того, например, на таблице "продукта", был бы я создавать класс "ProductManager", который имеет методы как:
GetProduct, GetAllProducts и т.д...
Любые указатели значительно получены.
По моему мнению (а также по мнению некоторых других людей), репозиторий должен быть интерфейсом, который скрывает доступ к данным в интерфейсе, имитирующем интерфейс коллекции. Вот почему репозиторий должен быть 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 работает достаточно хорошо для большинства запросов, которые мне нужно выполнить.
Вот мои мысли по поводу общих хранилищ:
Преимущество создания общего хранилища по сравнению с отдельным хранилищем для каждого объекта?
Я успешно использовал этот паттерн в NHibernate и не нашел никаких реальных недостатков.
Суть в том, что действительно общие репозитории - это немного красная селедка, но те же преимущества можно реализовать, если подойти к проблеме несколько иначе.
Надеюсь, это поможет.