Єдиний законна ін'єкція залежностей антішаблон , що я знаю це Service Locator шаблон, який є анти-моделлю , коли каркас DI використовується для цього.
Усі інші так звані антидіапазони DI, про які я чув, тут чи деінде, - це лише дещо конкретніші випадки загальних анти-моделей OO / Software design. Наприклад:
Перевиконання інжектора конструктором - це порушення єдиного принципу відповідальності . Занадто багато аргументів конструктора вказує на занадто багато залежностей; занадто багато залежностей вказує на те, що клас намагається зробити занадто багато. Зазвичай ця помилка корелює з іншими запахами коду, такими як незвично довгі або неоднозначні ("менеджер") назви класів. Засоби статичного аналізу можуть легко виявити надмірну аферентну / еферентну зв'язок.
Введення даних, на відміну від поведінки, є підтипом полтергейстського антидіаграму, при цьому "геїст є контейнером. Якщо класу потрібно знати про поточну дату та час, ви не вводите a DateTime
, що є даними; натомість ви вводите абстракцію над системним годинником (зазвичай я називаю свою ISystemClock
, хоча я думаю, що в проекті SystemWrappers є більш загальна ). Це не тільки правильно для DI; це абсолютно важливо для перевірки, так що ви можете перевірити різні за часом функції, не потребуючи їх дійсно чекати.
Декларація кожного життєвого циклу як Сінглтон є для мене прекрасним прикладом програмування культового культу і, в меншій мірі, в розмовному назві " об'єкт вигрібної ями ". Я бачив більше одинакових зловживань, ніж я пам'ятаю, і дуже мало цього стосується Д.І.
Ще однією поширеною помилкою є типи інтерфейсів, характерних для впровадження (із дивними іменами на кшталт IOracleRepository
), зробленими просто для того, щоб мати можливість зареєструвати його в контейнері. Це саме по собі є порушенням принципу інверсії залежності (лише тому, що це інтерфейс, не означає, що це справді абстрактно) і часто також включає розрив інтерфейсу, що порушує принцип розбиття інтерфейсу .
Остання помилка, яку я зазвичай бачу, - це "необов'язкова залежність", яку вони робили в NerdDinner . Іншими словами, є конструктор , який приймає ін'єкції залежностей, а й інший конструктор , який використовує реалізацію « по умовчанням». Це також порушує DIP і, як правило, призводить до порушень LSP , оскільки розробники з часом починають робити припущення щодо реалізації за замовчуванням та / або починати нові екземпляри, використовуючи конструктор за замовчуванням.
Як свідчить стара приказка, ви можете написати FORTRAN будь-якою мовою . Dependency Injection НЕ срібна куля , яка буде перешкоджати розробникам загвинчування їх управління залежностями, але це дійсно запобігти ряд поширених помилок / анти-шаблони:
...і так далі.
Очевидно, ви не хочете розробити рамки, щоб залежати від конкретної реалізації контейнерів IoC , наприклад Unity або AutoFac. Тобто, знову ж таки, порушення ДІП. Але якщо ви навіть думаєте про те, щоб зробити щось подібне, то, мабуть, ви вже зробили кілька помилок проектування, тому що введення залежностей - це загальноприйнята методика управління залежностями і не пов'язана з концепцією контейнера IoC.
Все, що може побудувати дерево залежності; можливо, це контейнер IoC, можливо, це тестовий модуль з купою макетів, можливо, це тестовий драйвер, який надає фіктивні дані. Ваша рамка не повинна хвилюватись, і більшість кадрів, які я бачив, не хвилюються, але вони все ще активно використовують ін'єкцію залежностей, щоб її можна було легко інтегрувати в IoC-контейнер, що вибирається кінцевим користувачем.
DI - це не ракетна наука. Просто намагайтеся уникати new
і static
крім випадків , коли є вагомі причини , щоб використовувати їх, наприклад, метод корисності , який не має зовнішніх залежностей, або службовий клас , який не міг би мати якийсь - небудь мети поза рамками (Interop обгорток і ключі словника є загальними прикладами це).
Багато проблем із структурами IoC виникають, коли розробники спочатку вчаться їх використовувати, а замість того, щоб насправді змінювати спосіб обробки залежностей та абстракцій, щоб відповідати моделі IoC, замість цього намагаються маніпулювати контейнером IoC, щоб відповідати очікуванням їх старий стиль кодування, який часто передбачав би високу взаємодію та низьку згуртованість. Неправильний код - це поганий код, використовує він техніку DI чи ні.