Использование InjectionFactory для внедрения DbContext, время жизни созданного экземпляра

У меня есть проект ASP.NET MVC5 с Unity в качестве DI-фреймворка.

Рассмотрим следующий код:

container.RegisterType<ApplicationDbContext>(
    new InjectionFactory(c => new ApplicationDbContext()));

Поскольку мои репозитории используют один и тот же DbContext, было бы целесообразно передать один и тот же экземпляр всем им. Однако каждый посетитель сайта должен иметь отдельный экземпляр контекста, а не работать с одним большим экземпляром «для всего сайта». Я предполагаю, что это уменьшает возможности иметь время жизни экземпляра только для текущего запроса.

Поскольку UnityConfig.RegisterComponents() находится в методе Application_Start(), я думаю, он создаст только один экземпляр для всего приложения. Какова наилучшая практика в этом случае? Я подумал о следующем:

  1. Создайте свою собственную фабрику для DbContext, которая возвращает синглтон, и внедрите эту фабрику в мои репозитории.
  2. Переместить UnityConfig.RegisterComponents() в Application_BeginRequest()

Я попытался найти InjectionFactory на сайте Microsoft, но безуспешно (http://msdn.microsoft.com/en-us/library/microsoft.practices.unity.injectionfactory%28v=pandp.51%29.aspx)

Какой наилучшей практике я должен следовать в этом случае? Я не хочу переусердствовать, какое самое простое рабочее решение?


person Adam Szabo    schedule 23.04.2014    source источник
comment
Связано: stackoverflow.com/questions/10585478/   -  person Steven    schedule 23.04.2014


Ответы (3)


Я не веб-разработчик, но читая книгу Dependency Injection With Unity, они упомянули специальный менеджер времени жизни, который можно использовать для одного HTTP-запроса — PerRequestLifetimeManager

Возможно, это подойдет для ваших нужд?

person Jacobs Data Solutions    schedule 02.01.2015
comment
Спасибо. Любой пример этого, адаптированный к моему коду в вопросе? - person Adam Szabo; 03.01.2015

Удалите заводские и замените на:

container.RegisterType<ApplicationDbContext>(new HierarchicalLifetimeManager());

Это приведет к экземпляру ApplicationDbContext для каждого запроса, а также вызовет удаление контекста в конце запроса.

person Paul Hiles    schedule 06.07.2016

Я думаю, что вам нужна модель единицы работы.

Взгляните на следующую ссылку

http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

person cheesesharp    schedule 23.04.2014
comment
Это обобщено. Единица рабочего образца. Это хорошая статья для того, что нужно, и ее следует читать независимо от того, что я беру из нее и резюмирую, как вы говорите. - person cheesesharp; 23.04.2014
comment
Использование репозитория внутри единицы работы — очень плохая идея. Я читал эту статью несколько раз, и мне захотелось побиться головой об стол. Вот статья получше: rob.conery.io/2014/03/04/ - person Jacobs Data Solutions; 21.09.2015
comment
Эта статья нарушает OCP. Вы не можете легко заменить структуру сущности на что-то другое. Конечно, реализация репозитория привязана к EF, это реализация интерфейса, идея в том, что вы можете реализовать новый, может быть, nhibernate, а затем он просто разрешается с помощью ioc. - person cheesesharp; 22.09.2015
comment
Довольно редко вам потребуется заменить один ORM на другой в одном программном проекте. Если вам нужна эта дополнительная абстракция, то обязательно создайте отдельный DAL, который инкапсулирует особенности вашей логики доступа к базе данных. Суть, которую Роб подчеркивает в статье, и я согласен с ней, потому что я учился в школе жестких ударов, состоит в том, что каждая операция с вашим хранилищем должна быть атомарной. В противном случае вы попадете в мир боли. Более того, сейчас я придерживаюсь мнения, что репозитории — это абстракции бизнес-логики, а не слой данных. - person Jacobs Data Solutions; 23.09.2015