Ninject — Entity Framework — изменение контекста во время выполнения

У нас тут какая-то интересная ситуация. Мы используем шаблон репозитория с Entity Framework, поэтому каждая таблица базы данных имеет свой собственный класс репозитория, который принимает экземпляр DbContext в своем конструкторе. Мы также используем Ninject для внедрения зависимостей. Мы определили один контекст, который будет создан во время данного запроса, поэтому, когда несколько репозиториев запрашивают DbContext, везде используется один и тот же экземпляр. Это позволяет нам следовать шаблону UnitOfWork, поэтому несколько вещей могут происходить в нескольких репозиториях, а одна фиксация фиксирует все изменения в базе данных.

Вот в чем проблема: мы также используем федерации SQL Azure, которые разбивают данные наших клиентов на несколько баз данных (сегментирование). Нам нужно иметь возможность переходить от одного члена федерации (базы данных) к другому в рамках одного и того же запроса, но мы хотим иметь возможность использовать одни и те же методы службы/репозитория, которые зависят от внедренного контекста. Наша первая мысль состояла в том, чтобы просто выполнить команду USE FEDERATION sql в существующем контексте, чтобы перейти к следующей базе данных, но, похоже, иногда она работает, а другие нет. После выполнения оператора мы видим, что базовое соединение в контексте действительно указывает на новый сервер, но по какой-то причине запросы, выполненные в этом контексте, в конечном итоге возвращают результаты из предыдущего соединения. Я предполагаю, что использование одного и того же экземпляра контекста в нескольких базах данных не является чем-то, что действительно поддерживается изначально, поскольку вы обычно запускаете новый контекст при подключении к новой базе данных. К сожалению, у нас есть куча репозиториев, которые создаются динамически с помощью Ninject, которые затем принимают один и тот же экземпляр контекста, поэтому, даже если мы создадим новый контекст для новой базы данных, у нас нет возможности сделать так, чтобы все существующие репозитории внезапно стали в зависимости от нового контекста, который мы только что запустили вместо того, который был создан по первоначальному запросу.

Вот несколько решений, которые мы можем придумать, но не уверены, как заставить какое-либо из них работать:

  1. Измените базу данных, используемую в существующем контексте (как объяснено выше, но, похоже, не работает)
  2. Замените введенный контекст для всех репозиториев новым, чтобы все существующие репозитории теперь зависели от другого контекста.
  3. Каким-то образом запросите у Ninject новый экземпляр всех репозиториев, передающих параметры, необходимые для контекста, как только он будет запрошен.

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


person Nick Olsen    schedule 01.05.2013    source источник
comment
Я бы постарался не допустить обмана Ninject. Разберитесь, что можно/нужно сделать в одном DbContext, и сделайте это. Затем сделайте следующий бит. Это все происходит в середине одного запроса? Как вы справляетесь с повторными попытками?   -  person Ruben Bartelink    schedule 02.05.2013
comment
Для таких сценариев мы обычно не используем Ninject, но так уж получилось, что эта конкретная вещь, которую мы делаем, зависит от 10-15 других репозиториев/сервисов, которые затем имеют свои собственные зависимости. Мы пытались избежать необходимости создавать все это самостоятельно, поскольку Ninject может сделать это за нас.   -  person Nick Olsen    schedule 02.05.2013
comment
Итак, что происходит — в ответ на какой тип запроса в каком типе приложения? Долговечны ли контексты? Разве невообразимо, что вы можете разделить базу данных? Являются ли эти 10-15 репозиториев частью одной единицы работы? Вам нужно больше объяснять, что является неотъемлемой частью того, что вы делаете. Я подозреваю, что в ходе объяснения вы обнаружите, что у вас будут четкие блоки работы, в рамках которых вам не нужно будет «менять контексты» и вникать в эти головоломки.   -  person Ruben Bartelink    schedule 02.05.2013


Ответы (1)


Решение состояло в том, чтобы просто полностью исключить Ninject из сценария. Не лучшее решение, но инструменты, которые мы используем, на самом деле не были предназначены для того, чтобы делать то, что мы хотели, в среде, в которой мы работаем.

person Nick Olsen    schedule 04.05.2013