Въпрос за DI и как да се решат някои проблеми

Аз съм начинаещ в Dependency Injection. Никога не съм използвал и дори не съм разбирал за какво точно става въпрос, но след последната ми атака по тази тема открих, че това е начин за разединяване на обект и неговите зависимости, след като те не са отговорни за инстанцирането на конкретните версии на неговите вече няма зависимости, тъй като сега контейнерът ще го направи вместо нас и ще достави готовия обект в ръцете ни.

Сега въпросът е; "кога трябва да го използвам?", ВИНАГИ??? Всъщност, тъй като съм начинаещ и никога не съм виждал проект, който използва този шаблон, не мога да разбера как трябва да го приложа към моите обекти на домейн!!! Струва ми се, че никога повече няма да инстанцирам обектите си и контейнерът винаги ще го прави вместо мен, но тогава идват някои съмнения...

1) Какво ще кажете за oobjects, че част от неговите зависимости идват от потребителския интерфейс, например;

public class User(String name, IValidator validator)

Да кажем, че получавам потребителското име от потребителския интерфейс, така че как conatiner ще го знае и все пак ще достави този обект за мен?

2) Има друга ситуация, пред която съм изправен; ако зависимостта сега е обект, който вече е инстанциран, да речем... SINGLETON обект, например. Видях, че има настройки относно обхвата на живота на инжектираната зависимост (говоря за Spring.NET, напр.; обхват на http заявка)... НО, заявката и други свързани с мрежата неща са на моя презентационен слой, така че как бих могъл да свържа както моя презентационен слой, така и моя домейн слой, без да наруша което и да е правило за проектиране (тъй като моят домейн не трябва да е напълно наясно къде се консумира, да няма зависимост от слоя и т.н.)

Нямам търпение да чуя всички вас. Много благодаря.


person Renato Gama    schedule 25.03.2011    source източник
comment
Много DI въпроси днес =) Вижте дали този отговор помага. :stackoverflow. com/questions/5433211/   -  person gideon    schedule 25.03.2011
comment
Полезно е @giddy, благодаря, но не е точно смисълът! =)   -  person Renato Gama    schedule 25.03.2011
comment
@Renato просто си помисли, че ще помогне да се обясни защо човек използва DI. =)   -  person gideon    schedule 25.03.2011
comment
@giddy наистина помага на моя приятел! Прочетох и подкрепих отговора ви, беше ми напълно ясно. Това, което се случва, е, че вече разбирам това, което обяснихте там, така че предполагам, че съмнението ми е малко по-далеч от този въпрос. Благодаря ти за загрижеността приятел! оценявам!   -  person Renato Gama    schedule 25.03.2011
comment
свързани: stackoverflow.com/questions/1943576/   -  person Mark Seemann    schedule 25.03.2011
comment
свързани: stackoverflow.com/questions/4835046/   -  person Mark Seemann    schedule 25.03.2011
comment
свързани: stackoverflow.com/questions/1475575/   -  person Mark Seemann    schedule 25.03.2011
comment
свързани: stackoverflow.com/questions/150980/   -  person Mark Seemann    schedule 25.03.2011
comment
@Mark благодаря, ще проверя всичко!!!   -  person Renato Gama    schedule 25.03.2011
comment
@Renato: Няма проблем. Повечето от вашите въпроси изглежда са от концептуален характер. Някои от връзките, които предоставих, може на пръв поглед да ви изглеждат неуместни, защото те питат за други контейнери и т.н., но трябва да можете да извлечете някои общи насоки от отговорите.   -  person Mark Seemann    schedule 25.03.2011


Отговори (3)


Като цяло, след като преминете към IoC, вие сте склонни да искате да регистрирате ВСИЧКО с IoC и контейнерът да изплюе напълно хидратирани обекти. Вие обаче извеждате някои валидни точки.

Може би една дефиниция на „зависимост“ е подходяща; в най-широк смисъл, зависимостта е просто набор от функционалности (интерфейс), които даден клас изисква конкретна реализация, за да може класът да работи правилно. По този начин повечето нетривиални програми са пълни със зависимости. За да се улесни поддръжката, обикновено се предпочита слабото свързване на всички зависимости. Въпреки това, дори когато сте слабо свързани, не е необходимо да автоматизирате инстанциране на зависимости, ако тези обекти изискват специализирана информация, с която не искате да замърсявате вашия IoC регистър. Целта е да се свърже свободно използването, а не непременно създаването.

Относно точка 1, някои IoC рамки не се справят добре с дадени външни параметри. Въпреки това обикновено можете да регистрирате делегат като фабричен метод. Този делегат може да принадлежи към обект като контролер, който получава външна информация от потребителския интерфейс. Влизанията са перфектен пример: създайте обект, да речем LoginController, и го регистрирайте в IoC като ваш ILoginController. Ще посочите този контролер на страницата си за вход, той ще бъде инжектиран, когато страницата за вход бъде създадена, и страницата за вход ще му предаде въведените идентификационни данни. След това контролерът ще извърши удостоверяване и ще има метод GetAuthenticatedUser(), който създава потребителски обект. Можете да регистрирате този метод с IoC като фабрика за потребители и всеки път, когато е необходим потребител, фабричният делегат или ще бъде оценен, или ще бъде предаден на едро на зависимия метод, който ще го извика, когато наистина има нужда от потребителя.

По точка 2, създаването на единичен екземпляр на обект е силна страна на модела IoC. Вместо да създавате истински сингълтон с частен конструктор на екземпляр, статичен екземпляр и статичен конструктор за създаване на екземпляр, вие просто регистрирате класа в IoC и му казвате да го инстанцира само веднъж и да използва този един екземпляр за всички заявки. Силата е гъвкавостта; ако по-късно искате да има повече от един екземпляр, просто променяте регистрацията. И в двата случая няма да нарушите никакви правила за модел на проектиране; изгледът винаги ще има инжектиран контролер, независимо дали този контролер е един и същ за всички страници или нов екземпляр на заявка.

person KeithS    schedule 25.03.2011

1) този конструктор вероятно не е правилният за използване, може да се окаже, че инжектирате валидатора на грешното място/начин.

2)Neighter View, нито Model, нито Controller трябва да са наясно, че има IoC, той трябва да се намира във фоновата архитектура (където MVC компонентите всъщност се инстанциират)

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

person Felice Pollano    schedule 25.03.2011

Трябва да използвате инжектиране на зависимост винаги, когато искате някое от следните предимства:

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

За да отговоря на другите ви въпроси:

1) Можете да конфигурирате много IoC контейнери, така че определени параметри на конструктора да могат да бъдат посочени, докато други се разрешават от контейнера. Въпреки това може да се наложи да помислите за рефакторинг на тази част от кода, тъй като UserFactory може да е по-подходящ, който приема зависимостта на валидатора и има NewUser метод, който взема потребителско име и връща нов потребител (или директно инстанциране, или разрешаване от контейнера).

2) Всяко приложение, което изграждате, ще има композиционен корен, където е конфигуриран вашият контейнер и основният обект е разрешен. Следователно всяко приложение ще има своя собствена IoC конфигурация, така че има очаквана връзка между типа на приложението и настройките за конфигурация. Всички общи регистрации на абстракция могат да бъдат поставени в конфигурационен код, който може да се споделя между всички приложения.

person devdigital    schedule 25.03.2011