
DI-контейнер на чистом JavaScript без TypeScript и reflect-metadata
alexander_kubarski 18 минут назад DI-контейнер на чистом JavaScript без TypeScript и reflect-metadata Средний 11 мин 561 JavaScript * Node.JS * TypeScript * Туториал TL;DRПосмотреть код целиком можно тут: скорее...
18 Temmuz'da Wellington'da en yüksek sıcaklık 14°C olacak mı?
В сфере искусственного интеллекта произошло заметное событие. alexander_kubarski 18 минут назад DI-контейнер на чистом JavaScript без TypeScript и reflect-metadata Средний 11 мин 561 JavaScript * Node. JS * TypeScript * Туториал TL;DRПосмотреть код целиком можно тут: скорее рассчитана на начинающих разработчиков, но для ее понимания потребуется некоторое время и базовое представление об архитектуре приложений и паттернах. Перед чтением рекомендую познакомиться с принципами DDD и SOLID, особенно с буквой (D).
Я уже давно пытаюсь придумать, как можно сделать достойный DI-контейнер на ванильном JavaScript. Несколько раз я уже подходил к этой задаче, пробовал разные варианты, но отсутствие полноценной рефлексии и строгой типизации каждый раз сильно ограничивало возможные решения. Конечно, можно явно перечислять зависимости, хранить их в статических свойствах классов или использовать отдельный реестр метаданных, даже парсить исходный код классов, но обычно в какой-то момент такой контейнер либо становится слишком многословным, либо начинает напоминать плохо реализованный service locator.
Технические детали
В этот раз мне, кажется, удалось найти более интересный подход (возможно его находили и до меня). Он основан на том, что в JavaScript классы являются обычными значениями: их можно динамически создавать, передавать в функции, дополнять метаданными и использовать как токены. В результате получился небольшой DI-контейнер без TypeScript, декораторов и reflect-metadata.
Пока это эксперимент и попытка проверить саму идею, а не готовая библиотека. Тем не менее результат уже выглядит достойно, и после небольшой доработки я вполне мог бы попробовать использовать такой подход в реальном проекте. В статье разберем, как устроен контейнер, почему я решил отказаться от автоматического анализа конструкторов и как применить его в небольшом DDD-примере с корзиной товаров.
Когда речь заходит о dependency injection в JavaScript, разговор обычно быстро сводится к TypeScript, декораторам и reflect-metadata. Класс помечается как injectable, типы параметров конструктора превращаются в метаданные, а контейнер пытается самостоятельно понять, что именно нужно передать в каждый аргумент. При этом сам JavaScript уже содержит почти все, что нужно для простого DI-контейнера.
Отраслевые последствия
Класс в JavaScript является обычным runtime-значением. Его можно создать внутри функции, передать в другую функцию, использовать как ключ в Map, дополнить собственными свойствами и вернуть наружу. Значит, список зависимостей можно объявить прямо в момент создания класса, не пытаясь восстановить его позднее из типов, имен аргументов или результата Function.
Далее мы соберем небольшой DI-контейнер на чистом JavaScript, добавим singleton, scoped и transient lifetime, а затем применим его в более реалистичном примере с DDD-корзиной. Доменный слой останется независимым от контейнера, а DI будет отвечать только за сборку application и infrastructure слоев.
Событие, по словам экспертов, усилит конкуренцию в сфере ИИ.




