Я все ще на початку вивчаю Scala на додаток до Java, і я не зрозумів, як там робити DI? можу чи повинен я використовувати існуючу бібліотеку DI, це слід робити вручну чи є інший спосіб?
Відповіді:
Стандартні фреймворки Java DI зазвичай працюють із Scala, але ви також можете використовувати мовні конструкції для досягнення того самого ефекту без зовнішніх залежностей.
Нова бібліотека ін'єкцій залежностей, спеціально для Scala, - це Діка Уолла SubCut .
У той час як стаття Йонаса Бонера, на яку посилається відповідь Ден Сторі, наголошує на екземплярах, пов’язаних із часом компіляції, та статичному введенні (за допомогою змішань), SubCut базується на ініціалізації незмінних модулів під час виконання та динамічній ін’єкції шляхом запиту пов’язаних модулів за типом, іменами рядків, або Scala. Назви символів.
Детальніше про порівняння з шаблоном Cake можна прочитати в документі GettingStarted .
Саму інжекцію залежностей можна зробити без будь-якого інструменту, фреймворку або підтримки контейнера. Вам потрібно лише видалити new
s з коду і перемістити їх у конструктори. Втомлива частина, яка залишається, - це підключення об’єктів на «кінці світу», де контейнери дуже допомагають.
Хоча з макросами Scala 2.10 ви можете генерувати код проводки під час компіляції та мати автоматичне підключення та безпеку типу.
Нещодавній проект ілюструє DI, заснований виключно на вприскуванні конструктора: zalando / grafter
Що поганого у введенні конструктора знову?
У Scala існує безліч бібліотек або підходів до введення залежностей . Grafter повертається до основ введення залежностей, просто використовуючи введення конструктора : без відображення, без xml, без анотацій, без успадкування або самотипів.
Потім Grafter додає до інжектора конструктора лише необхідну підтримку для:
- створити екземпляр програми на основі компонентів із конфігурації
- точна настройка проводки (створення однотонних)
- протестуйте додаток, замінивши компоненти
- запуск / зупинка програми
Grafter націлений на всі можливі програми, оскільки він зосереджений на об'єднанні лише 3 ідей:
- класи класів та інтерфейси для компонентів
- Екземпляри зчитувача і безформні для конфігурації
- переписування дерев і кіама для всього іншого!
Я сам цього не робив, але більшість фреймворків DI працюють на рівні байт-коду (AFAIK), тому має бути можливо використовувати їх з будь-якою мовою JVM.
Попередні публікації висвітлювали методи. Я хотів додати посилання на виступ Мартіна Одерського у травні 2014 року про цілі мови Scala. Він визначає мови, які "потребують" контейнера DI для введення залежностей, як погано реалізовані. Я з цим особисто погоджуюсь, але це лише думка. Здається, це вказує на те, що включення залежності DI у ваш проект Scala є неідіоматичним, але знову ж таки така думка. Практично кажучи, навіть з мовою, призначеною для внутрішньої інжекції залежностей, існує певна послідовність, отримана за допомогою контейнера. Варто врахувати обидві точки зору для своїх цілей.
Я б запропонував вам спробувати дистадж (відмова від відповідальності: я автор).
Це дозволяє зробити набагато більше, ніж типовий DI, і має безліч унікальних рис :
scala-reflect
(але підтримує всі необхідні функції системи типів Scala, як вищі типи).Ви також можете переглянути нашу бесіду на Functional Scala 2019, де ми обговорили та продемонстрували деякі важливі можливості незручності.
На додаток до відповіді Ден Сторі, я писав у блозі про варіант DI, який також використовує лише мовні конструкції, але не згадується в дописі Джонаса: Введення вартості за риси (посилання на web.archive.org зараз). Цей шаблон дуже добре працює для мене.