Управление подключениями с помощью шаблона Generic Repository

Я создаю сайт, используя Entity Framework 4.1 и mvc3. Я использую шаблон универсального репозитория:
http://www.tugberkugurlu.com/archive/generic-repository-pattern-entity-framework-asp-net-mvc-and-unit-testing-треугольник. Я использую ninject для внедрения моих конкретных репозиториев в контроллеры. Моя проблема в том, что каждый из моих dbcontext отличается, и я не могу выполнять сложные запросы без того, чтобы код кричал что-то вроде «разные контексты не могут использоваться в одном запросе». Я попытался использовать подход «singleton», но затем код выкрикнул что-то вроде «пытался ввести удаленный объект (исключение нулевой ссылки)». Кто-нибудь знает, что я делаю неправильно?


person mashta gidi    schedule 03.05.2012    source источник


Ответы (2)


Шаблон Singleton — это анти-шаблон, которого следует избегать. Это приводит к трудно тестируемому коду со всевозможными побочными эффектами (например, удаленный DbContext).

UnitOfWork управляет операциями в разных репозиториях. Он будет отслеживать все внесенные изменения, а затем запишет эти изменения в правильном порядке в вашу базу данных. DbContext уже реализует шаблон UnitOfWork (хотя лучше скрыть DbContext за пользовательским интерфейсом UnitOfWork).

Если вы уже используете внедрение зависимостей через NInject, вы почти их! Вы должны изменить конструкторы вашего репозитория, чтобы использовать DbContext:

public class MyRepository
{
   private _unitOfWork;

   public MyRepository(DbContext unitOfWork)
   {
      _unitOfWork = unitOfWork;
   }

   ....
}

Если вы затем подключите DbContext к NInject с режимом InRequestScope, все должно работать . Затем ваш DbContext будет использоваться всеми репозиториями, и Ninject удалит его в конце вашего запроса.

person Wouter de Kort♦    schedule 03.05.2012
comment
Вы имеете в виду, что конструктор моего репозитория должен получить dbContext, и ninject будет знать, что нужно автоматически вводить dbcontext в класс репозитория, когда он вызывается в контроллере? - person mashta gidi; 05.05.2012
comment
кроме того, я использую общий репозиторий, как показано в этой статье: tugberkugurlu.com/archive/ Как я могу использовать там конструктор репозитория? - person mashta gidi; 05.05.2012
comment
да. Я имею в виду, что конструктор вашего репозитория должен принимать dbContext. Если вы затем используете NInject для внедрения dbContext с InRequestScope (это означает, что для каждого запроса будет один общий dbContext), тогда он должен работать. Насколько я вижу, GenericRepository следует изменить, чтобы он принимал dbContext в своем конструкторе, а не создавал его для каждого репозитория. - person Wouter de Kort♦; 05.05.2012

Не уверен, понял ли я ваш вопрос или нет, но ваши репозитории должны иметь возможность работать в «единице работы», которая будет иметь один контекст базы данных.

Я считаю, что лучше всего начать эту единицу работы с запроса на начало, который вы можете настроить в своем файле global.asax (и запрос на завершение для разрыва).

person Keith Nicholas    schedule 03.05.2012
comment
Единица работы - это то, что я еще не пробовал. Можете ли вы сказать мне, почему при попытке использовать одиночный шаблон Ton я получил нулевую ссылку (пытаясь получить доступ к удаленному объекту) - person mashta gidi; 03.05.2012