Зависимост инжектиране (зависимостта инжекция) - документация на корпуса 1

ASP.NET ядро ​​поддържа зависимостта инжекция. ASP.NET Основни приложения използват интегрирани услуги рамка, които са вградени в методите за стартиране класа и услуги за кандидатстване могат да бъдат конфигурирани да DI. Контейнерът за услуга по подразбиране осигурява минимален набор от функции, и не замества други контейнери.

Зависимост инжектиране (DI) - технология, която се използва в максимална степен да се разделят обекти и зависимости. Вместо директен монтаж на компоненти или използването на статични връзки, възрази, че този клас трябва да извърши някакво действие, имайки предвид този клас по различен начин. Най-често срещаните класове състояние на зависимост чрез конструктора, които им позволяват да се спазва принципът на изрични зависимости. Този подход е известен като "конструктор инжектирането".

Ако класовете които използват DI, техните компоненти не зависят от пряко помежду си. Това се нарича принцип на зависимостта инверсия. който гласи, че "модули на високо равнище не трябва да зависят от модули от ниско ниво. - и двамата трябва да зависи от абстракции" Вместо да се използват конкретни реализации, попитайте за класовете за водочерпене (обикновено интерфейс), които се предоставят, за да ги след създаването. Премахване на зависимости интерфейси и предавателни приложения на тези интерфейси като параметри е също пример стратегия дизайн модел на.

Ако системата използва DI, когато много класове се използват в зависимост от строителя (или свойства), е полезно за някои класове са свързани с необходимите зависимости. Тези класове са наречени контейнери. те също така се нарича инверсия на контрол контейнер (IOC) или ди контейнери. Контейнер - това е по принцип, фабриката, която предоставя копия на необходимите видове. Ако имате този вид пристрастяване, както и съществуващите контейнери за предоставянето на тези отношения, зависимости ще бъдат създадени като част от исканата инстанция. По този начин сложни зависимости Осигурява клас без твърд код на обект. Освен това, контейнерите обикновено управлява целия жизнен цикъл на обекта в рамките на заявлението.

ASP.NET ядро ​​включва проста вграден контейнер (представлявана от интерфейса IServiceProvider), която по подразбиране поддържа конструктор инжекция и ASP.NET предоставя определени услуги чрез DI. ASP.NET контейнер работи с двата вида услуги. По-късно в тази статия, услугите, които наричаме типове, които се управляват от МОК контейнер ASP.NET ядро. Можете да регулирате вградените контейнерни услуги с използване на метода ConfigureServices клас Startup.

В тази статия, ние погледнете как зависимостта инжекция се прилага във всички ASP.NET приложения. Зависимост инжектиране в MVC са отразени в член зависимостта инжекция и контролери `.

ConfigureServices Startup Метод клас дефинира услугите, които ще се използват при прилагането, включително функциите на платформи като Entity Framework ядро ​​и ASP.NET MVC ядро. Първоначално IServiceCollection. която се предава ConfigureServices. Има само няколко услуги. Ето един пример за това как да добавите допълнителни услуги към контейнера с помощта на такива методи за разширяване като AddDbContext. AddIdentity и AddMvc.

Функции и мидълуер ASP.NET използва един метод за разширяване AddService. да се регистрират всички услуги, които изискват тази функция.

Можете да заявите специфични услуги чрез методи за стартиране. Cm. Стартирайте приложението.

Можете да конфигурирате приложението така, че да използва различните функции на рамката, и можете да работите с ConfigureServices. да създадат свои собствени услуги.

Можете да се регистрирате собствените си услуги. Първият тип е общ вид (обикновено интерфейс), която ще бъде поискано от съда. Вторият тип е родово определен тип образец контейнер и които ще бъдат използвани за извършване на такива заявки.

Всеки services.Add повикване Услуги с добавена. Например, services.AddMvc () добавя услуга, която е необходима MVC.

метод AddTransient асоциира абстрактно със специфичните видове услуги, копие от който се генерира за всеки субект, който ги поиска. Това е известно като експлоатационен цикъл. Важно е да се избере най-подходящата за жизнения цикъл на услугата, която се регистрирате. В случай на нова инстанция на услугата, предоставяна на всеки клас, което го изиска? Трябва нова инстанция да се използва по време на заявката? Ако един случай се използва по време на целия жизнен цикъл на заявлението?

В примера за тази статия, има един контролер CharacterController. Неговият метод Index показва актуалния списък на героите и инициализира събиране, ако има такива, все още. Въпреки, че това приложение се използва рамката Entity и ApplicationDbContext клас. те не са видими в контролера. Вместо това, на механизъм за достъп до конкретни данни "крият" зад ICharacterRepository интерфейс. който следва хранилище модел. ICharacterRepository инстанция по искане на дизайнера и се възлага на затворена сфера, която след това се използва за достъп до желания символ.

ICharacterRepository определя два метода, които са необходими за контролера за работа с случаи характер.

Интерфейсът се осъществява с помощта на определен тип CharacterRepository.

Методът, който се използва с DI CharacterRepository клас е най-често срещаният модел, и можете да следвате да може да работи с всички услуги - не само в "хранилище" или класове на достъп до данните.

Имайте предвид, че CharacterRepository искания към вашия дизайнер ApplicationDbContext. Често зависимостта инжекция се използва във веригата, тоест, всеки иска зависимостта може да поиска собствената си зависимост. Контейнерът е отговорна за използването на всички зависимости в дървото и се връща пълната гама от услуги.

Създаване на исканата обекта и всички обекти, от които се нуждае, често се нарича графиката на обекти. По същия начин, набор от свързаното зависимост се нарича дърво на зависимост или зависимост графика.

В този случай ICharacterRepository ApplicationDbContext и трябва да бъдат регистрирани в съда за обслужване в ConfigureServices Startup. ApplicationDbContext конфигуриран като се използва метод разширение AddDbContext на. По-долу показва CharacterRepository вид на регистрация:

Рамковата контекст лица трябва да бъде добавен към контейнера за услуга чрез обхват на ниво. Това става автоматично, ако използвате методите за помощни, както е показано по-горе. Хранилища се използват с Entity Framework, трябва да има същия жизнен цикъл.

Бъдете внимателни, когато се използва с обхват услуга от Сингълтън. Ако това се случи, ние ще обслужва неправилно състояние при обработката на следващи заявки.

ASP.NET услуги могат да бъдат конфигурирани от следните жизнен цикъл:

Преходно Преходно услуги се създават всеки път, когато се изисква. Този цикъл на живот е най-добре да не подходящи особено смислен, "леки" услуги. С обхват с обхват услуги са създадени за всяка заявка. Singleton Singleton услуги са създадени веднъж при поискване, а след това всяка следваща заявка използва една и съща инстанция. Ако приложението изисква Сингълтън, когато контейнерът за обслужване управлява жизнения цикъл на дадена услуга, трябва да се приложи Сингълтън модел и управление на жизнения цикъл на обект в класната стая.

Услугите могат да бъдат регистрирани чрез съда по различни начини. Вече видяхме как да се регистрирате за услуга от този тип, като се посочва определен тип, които ще бъдат използвани. В допълнение, можете да използвате във фабриката, които след това ще създаде желаната инстанция. Третият подход е, че можете директно да посочите пример за правилния тип, а след това на контейнера никога не се опитва да създаде инстанция.

За да ви покажа разликата между регистрацията на цикъла на живот и възможности, ние ще използваме прост интерфейс, който осигурява една или повече задачи в сделка с уникален идентификатор, OperationID. В зависимост от това как ние се създаде жизнения цикъл на услугата, съдът ще даде едни и същи или различни инстанции на този клас на услуга по желание. За да стане ясно какво се иска от жизнения цикъл, ние ще създадем един вид за всяка от жизнения цикъл:

Ние също така изпълнява всички тези интерфейси с помощта на класа на операция. която взема своя конструктор GUID или създава нов GUID. ако те не съществуват.

Освен това, във всеки тип ConfigureServices добавени към проектанта в зависимост от съответния цикъл zhiznenngogo:

Имайте предвид, че IOperationSingletonInstance използва например ID Guid.Empty. така че ще бъде празен, когато използването на този тип. Също така сме регистрирали OperationService. който зависи от други видове операции. така че това ще бъде празна в рамките на заявка, ако услугата получава една и съща инстанция, както и контролер или другата страна за получаване на различни видове операции.

За да ви покажем целия жизнен цикъл обект в рамките на и между различните искания в молбата, ние сме включили и пример OperationsController. който пита за всички видове стил IOperation. и OperationService. метод действие Index след това показва всички стойности OperationId контролери и услуги.

Сега ние правим две отделни запитвания към начина на действие на контролера:

Зависимост инжектиране (зависимостта инжекция) - документация на корпуса 1
Зависимост инжектиране (зависимостта инжекция) - документация на корпуса 1

Вижте как OperationId ценности се различават при подкана и между запитвания.

  • Преходни обекти са винаги различни; нов екземпляр на контролера се предоставя на всеки сервиз.
  • Тръгва по обекти са винаги едни и същи, когато една и съща заявка, но се различават по различни въпроси.
  • Singleton обекти са едни и същи за всяка заявка, както и за всеки обект.

Услуги на разположение заявка ASP.NET от HttpContext. включени в RequestServices.

Колекция RequestServices представлява услугите, които са конфигуриране и поискали като част от тяхното прилагане. Когато обектите са определени в зависимост, от която се нуждаят видовете RequestServices. вместо ApplicationServices.

Като цяло, не трябва да използвате тези свойства директно, а вместо това трябва да поискат тип, който искате клас, строителя и нека рамка-те прилагат тези зависимости. Тези класове са по-лесни за изпитване (вж. Тестване), и те не зависят един от друг.

В приложенията ви почти винаги RequestServices да се използва. и във всеки случай, че нямате достъп до тези свойства директно. Вместо това, да поиска необходимите услуги чрез конструктора на класа.

И ако в класовете си прекалено много зависимостта инжекция? Обикновено това означава, че вашият клас е твърде претоварен и нарушава принципа SRP - принципът на единния отговорност. Трябва да се промени този клас, преместване на някои от неговите функции в новия клас. Имайте предвид, че класовете на контролера трябва да се фокусират върху потребителския интерфейс, така че бизнес правила и достъп до данните, трябва да се съхранява в класове в съответствие с разделението на отговорностите.

По отношение на достъпа до информация, можете да се приложат в DbContext на контролера (ако сте добавили ЕФ в сферата на услугите за контейнери ConfigureServices). Някои хора предпочитат да използват хранилище интерфейс, вместо вграждане DbContext директно. С помощта на интерфейса за капсулиране на данни логика достъп на едно място може да намали броя на местата, където ще трябва да се направят промени, ако има промени в базата данни.

Интегрирани услуги се нуждае от контейнер дръжки основната рамка. Въпреки това, разработчиците могат лесно да замени друг контейнер. Обикновено метод ConfigureServices връща нищожно. но ако това е бил променен, така че да се върне на IServiceProvider. че е възможно да се приспособи и да се върне в друг контейнер. Има много МОК контейнери на разположение за .NET. Ще се опитаме да се добави позоваване на прилагането на DNX контейнери. Този пример използва Autofac пакет.

Първо добавете подходящи контейнери в опаковките зависимости имот в project.json:

След това, поставете съда в ConfigureServices и да се върнете IServiceProvider: