Na obsah stránky

DIP, IoC a DI - díl první

Aleš Roubíček | | # permalink

Zmatení pojmů je úžasná věc. Něco si myslíte a tak řeknete něco, co vás napadne jako první. A většinou je to blbost. Ale lidi se to naučili tolerovat, protože stejný blbosti děláme všichni. Nakonec si nikdo nerozumí, ale všichni dělaj, jako že jo. Nechtěj vypadat jako blbci.

Disclaimer: Článek si neklade za cíl se do někoho navážet, někoho ranit nebo zesměšňovat. Klade si za cíl otevřít otázky nad obecně přijímanými pravdami.

Dependency Inversion Principle, Inversion of Control a Dependency Injection mají tolik vzájemně společných slov, že musí být i blbci jasné, že spolu úzce souvisí. A přitom je to blbost. Existují jistá místa, kde se můžou vzájemně dotýkat, ale vůbec to tak nemusí být.

Začněme jednoduchým příkladem z praxe. Běžně začneme tak, že si vytvoříme rozhraní pro repository IRepository<TEntity> a prdneme ho do projektu/namespace MyAwesomeApp.Data. To je jasný, repository přece patří do datový vrstvy! Ne asi. Pak si uděláme konkrétní implementace jako MyAwesomeApp.Data.ArticleRepository : IRepository<Article> a podobně. Každá si v konstruktoru vytvoří DataContext, který se nějak nakonfiguruje. Ten pak obalíme svejma metodama a spokojeně rozšiřujeme rozhraní třídy s každým dalším dotazem…

Pak si někde přečteme, že testovatelnost, DI a tak, a tak teda uděláme přetížení konstruktoru, který bude brát DataContext odněkud z venku, ale abychom nechodili moc daleko, to venku bude původní přetížení, který jen zavolá tohle nové. Poor men's DI ve své nejčistší formě.

Pro jistotu se zeptám: Vidíte tu nějaký Inversion of Control nebo uplatnění Dependency Inversion Principle? Houby s octem! DI s nimi tedy určitě nesouvisí. Pokud vám někdo tvrdí, že IoC je obecný princip a DI je jeho konkrétní implementace, neříká pravdu. :)

Ok, pokračujeme dál. Vytvoříme si ten doménovej model. Vlastně to jsou jedna k jedný entity z databáze, ale who cares? Je třeba si z checklistu odškrtnout další zkratku začínající na D. Taková malá úlitba OO bohům. Na to si vytvoříme novej projekt MyAwesomeApp.BusinessLogic, aby bylo jasný, že děláme ten business a má to nějakou logiku. Sem krom entit z databáze nasereme taky všemožný statický helpery a podobně, co zrovna budeme potřebovat znovu použít. No a protože některý helpery budou potřebovat naše entity ukládat do databáze a taky se na ně dotazovat, tak z nich uděláme teda instanční třídy a necháme si nainjektovat nějaký repository. Třeba tak: PublishingManager(ArticleRepository repository).

Držíme se dependency injection. No a proto, aby nám vůbec šla ta repository nainjectovat, přidáme referenci na naši datovou vrstvu. Tak určitě. Jak jinak byste to chtěli přece řešit?

Našli jste v článku chybu? Máte námět na reportáž? Založte mi ticket.