Як зробити ін’єкцію залежності в масштабі?


75

Я все ще на початку вивчаю Scala на додаток до Java, і я не зрозумів, як там робити DI? можу чи повинен я використовувати існуючу бібліотеку DI, це слід робити вручну чи є інший спосіб?


1
Див.
Ін’єкцію

Відповіді:


61

Стандартні фреймворки Java DI зазвичай працюють із Scala, але ви також можете використовувати мовні конструкції для досягнення того самого ефекту без зовнішніх залежностей.


посилання дає мені справді хороший огляд із багатьма прикладами. дуже тобі дякую.
Фабіан

4
fwiw, ця стаття була одним із найсильніших натхнення, яке я мав, коли вперше почав вивчати Scala.
Даніель К. Собрал,

Мені цікаво, як реалізується шаблон кола, коли служба чи реєстр може потребувати різної кількості екземплярів компонента. Наприклад, що, якщо WarmerComponentImpl у зв’язаному прикладі потребував двох різних екземплярів OnOffDeviceComponent для виконання своєї роботи?
Мітч Блевінс,

1
@MitchBlevins, погляньте на розділ "кілька реалізацій" у посібнику Інжекція залежностей у Scala .
adamw

Для загального огляду, як робити DI в Scala. Погляньте на: blog.knoldus.com/2014/07/04/dependency-injection-scala
Sky

15

Нова бібліотека ін'єкцій залежностей, спеціально для Scala, - це Діка Уолла SubCut .

У той час як стаття Йонаса Бонера, на яку посилається відповідь Ден Сторі, наголошує на екземплярах, пов’язаних із часом компіляції, та статичному введенні (за допомогою змішань), SubCut базується на ініціалізації незмінних модулів під час виконання та динамічній ін’єкції шляхом запиту пов’язаних модулів за типом, іменами рядків, або Scala. Назви символів.

Детальніше про порівняння з шаблоном Cake можна прочитати в документі GettingStarted .


9

Саму інжекцію залежностей можна зробити без будь-якого інструменту, фреймворку або підтримки контейнера. Вам потрібно лише видалити news з коду і перемістити їх у конструктори. Втомлива частина, яка залишається, - це підключення об’єктів на «кінці світу», де контейнери дуже допомагають.

Хоча з макросами Scala 2.10 ви можете генерувати код проводки під час компіляції та мати автоматичне підключення та безпеку типу.

Див. Ін’єкцію залежностей у посібнику Scala


2
Настільки мало хто це усвідомлює, що я використовую це як запитання для співбесіди.
Тім Баррас

2

Нещодавній проект ілюструє DI, заснований виключно на вприскуванні конструктора: zalando / grafter

Що поганого у введенні конструктора знову?

У Scala існує безліч бібліотек або підходів до введення залежностей . Grafter повертається до основ введення залежностей, просто використовуючи введення конструктора : без відображення, без xml, без анотацій, без успадкування або самотипів.

Потім Grafter додає до інжектора конструктора лише необхідну підтримку для:

  • створити екземпляр програми на основі компонентів із конфігурації
  • точна настройка проводки (створення однотонних)
  • протестуйте додаток, замінивши компоненти
  • запуск / зупинка програми

Grafter націлений на всі можливі програми, оскільки він зосереджений на об'єднанні лише 3 ідей:

  • класи класів та інтерфейси для компонентів
  • Екземпляри зчитувача і безформні для конфігурації
  • переписування дерев і кіама для всього іншого!

1

Я сам цього не робив, але більшість фреймворків DI працюють на рівні байт-коду (AFAIK), тому має бути можливо використовувати їх з будь-якою мовою JVM.


2
Одним із стандартних фреймворків Java DI, який я успішно використовував у Scala за останні кілька років, є PicoContainer. (І ви можете використовувати ін’єкцію конструктора замість ін’єкції сетера, щоб зберегти незмінність.)
Seth Tisue

Spring ME - це система введення залежностей, яка використовує аналіз вихідного коду для досягнення більшості того, що робить повна Spring під час виконання. Як наслідок, ви отримуєте майже нульовий контекст програми, не залежно від будь-якої зовнішньої бібліотеки. Не знаю, чи хотів би я використовувати його для Scala.
Вільфред Спрінгер

1

Попередні публікації висвітлювали методи. Я хотів додати посилання на виступ Мартіна Одерського у травні 2014 року про цілі мови Scala. Він визначає мови, які "потребують" контейнера DI для введення залежностей, як погано реалізовані. Я з цим особисто погоджуюсь, але це лише думка. Здається, це вказує на те, що включення залежності DI у ваш проект Scala є неідіоматичним, але знову ж таки така думка. Практично кажучи, навіть з мовою, призначеною для внутрішньої інжекції залежностей, існує певна послідовність, отримана за допомогою контейнера. Варто врахувати обидві точки зору для своїх цілей.

https://youtu.be/ecekSCX3B4Q?t=1154


1

Я б запропонував вам спробувати дистадж (відмова від відповідальності: я автор).

Це дозволяє зробити набагато більше, ніж типовий DI, і має безліч унікальних рис :

  1. distage підтримує кілька конфігурацій (наприклад, ви можете запускати свій додаток з різними наборами реалізацій компонентів),
  2. distage дозволяє вам правильно ділитися залежностями між вашими тестами та легко запускати однакові тести для різних реалізацій ваших компонентів,
  3. distage підтримує ролі тому ви можете запускати кілька служб в рамках одного процесу, обмінюючись залежностями між ними,
  4. distage не залежить від scala-reflect (але підтримує всі необхідні функції системи типів Scala, як вищі типи).

Ви також можете переглянути нашу бесіду на Functional Scala 2019, де ми обговорили та продемонстрували деякі важливі можливості незручності.


0

Я показав, як я створив дуже простий функціональний DI-контейнер у масштабі, використовуючи тут 2.10 .


0

На додаток до відповіді Ден Сторі, я писав у блозі про варіант DI, який також використовує лише мовні конструкції, але не згадується в дописі Джонаса: Введення вартості за риси (посилання на web.archive.org зараз). Цей шаблон дуже добре працює для мене.


посилання на блог мертве, чи можете ви детальніше
пояснити
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.