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

Имам проект ASP.NET MVC5 с Unity като DI framework.

Разгледайте следния код:

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