.Net - Разделение шаблона единицы работы для нескольких ORM - PullRequest
4 голосов
/ 09 апреля 2011

Моя текущая структура приложения:

  • Сборка моделей
  • Сборка данных
    • Определяет интерфейсы репозитория, которые будут реализованы с помощью ORM
  • Сборка ORM
    • Реализует интерфейсы хранилища из Сборки данных
    • Использует единицу (контейнер IoC) для регистрации от Data.IRepository<> до ORM.GenericRepository<>
  • Бизнес-сборка
    • Ссылка на сборки данных и моделей
    • Использование единства для разрешения типов IRepository<>
  • Интерфейс сборки
    • Ссылка на бизнес-сборку

Эта структура по существу отделила бизнес-уровень от ORM, реализующего IRepository<T>.

Одно из преимуществ этой развязкиСтруктура заключается в том, что я должен быть в состоянии относительно легко заменить ORM - например, перейти от Entity Framework к NHibernate или просто обновить существующий ORM.В настоящее время я сначала использую код EF 4.1 и собираю другую сборку для NHibernate.

Я рассматриваю возможность реализации шаблона Unit of Work.

Я прочитал, что этот шаблон должен использоватьсяна бизнес-уровне (с интерфейсами, определенными в моей сборке данных и реализованными в сборке ORM, как я делал с шаблоном хранилища).В настоящее время все созданные экземпляры репозиториев имеют свой собственный DbContext / session, и его время жизни установлено равным таковому для репозитория - что может быть плохо - моя проблема в том, что я не уверен, возможно ли реализовать шаблон Unit of Work, который будет работать сразные ORM (скорее, это, вероятно, и я просто не в курсе).

Это единственное, что приходит на ум:

Создать IUnitOfWork в моей сборке данных, которая имеетфункция: object GetCurrentSession();, затем иметь аргумент в конструкторе репозиториев в сборке ORM и привести его к соответствующему сеансу / DbContext (если NHibernate, то ISession, если Entity Framework, то DbContext)

Я быпризнателен, если кто-то имеет представление об этой ситуации.

1 Ответ

0 голосов
/ 11 апреля 2011

Возможно, я нашел решение (еще не пробовал):

В сборке данных:

public interface IUnitOfWork : IDisposable
{
   void Start();
   T Current<T>();
   // IDisposable stuff
}

В сборке ORM:

public class GenericRepository<T> : IRepository<T>
    where T : PersistentEntity
{
    private ISession CurrentSession;

    public GenericRepository(IUnitOfWork uow)
    {
         CurrentSession = uow.Current<ISession>();
    }

    // other repository stuff here
}

public class NHhibernateUnitOfWork : IUnitOfWork
{
   private ISession CurrentSession;

   public void Start()
   {
      // instantiate CurrentSession
   }

   T Current<T>()
   {
      if(typeof(T) is ISession)
         return (T)CurrentSession;
      else
         return new NotImplementedException();
   }
}

// in the prism module
container.Resolve(typeof(IUnitOfWork), typeof(NHhibernateUnitOfWork));

В бизнес-сборке:

IUnitOfWork uow = container.Resolve<IUnitOfWork>();
using(uow.Start())
{
    IRepository custRepo = container.Resolve<IRepository<Customer>>(uow);
    // do stuff here with cust repo
}

Это просто подтверждение концепции отделения IUnitOfWork от конкретной реализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...