Angular — это достаточно большой фреймворк. Задокументировать и написать примеры использования для каждого кейса просто невозможно. И механизм внедрения зависимостей не исключение. В этой статье я расскажу о возможностях Angular DI, о которых вы почти ничего не найдете в официальной документации. Документация говорит нам следующее: Injects a token from the currently active injector. Must be used in the context of a factory function such as one defined for an InjectionToken. Throws an error if not called from such a context. И дальше мы видим использование функции inject в примере с tree shakable токеном: Это все, что говорит нам документация. Описание функции немного размыто, и не до конца понятно, в каком именно контексте можно использовать inject. Поэтому я провел нехитрый эксперимент и выяснил, что функция прекрасно работает: В фабриках tree shakable провайдеров. В фабриках провайдеров. В конструкторах сервисов. В конструкторах модулей. Так как фабричная функция InjectionToken не может иметь аргументы, inject — единственный способ получить данные из инжектора. Но зачем нам эта функция в сервисах, если можно просто указать необходимые зависимости прямо в параметрах конструктора? Рассмотрим небольшой пример. Допустим, мы имеем абстрактный класс Storage, который зависит от класса Logger: Любой другой класс, реализующий класс Storage, должен предоставить ему его зависимость в ручном режиме. Если зависимостей много, это может оказаться очень неприятным делом: Есть два выхода из ситуации — передавать в родительский класс инжектор, из которого будут извлекаться все необходимые зависимости, либо просто использовать функцию inject! Так мы избавим дочерние классы от проксирования лишних зависимостей: Профит! Давайте обратимся к исходному коду. Нас интересует приватная переменная _currentInjector, функция setCurrentInjector и сама функция inject. Если внимательно посмотреть, то работа функции inject становится совершенно очевидной: вызов функции setCurrentInjector присваивает в приватную переменную _currentInjector переданный инжектор, возвращая предыдущий; функция inject достает из _currentInjector значение по переданному токену. Это настолько просто, что мы совершенно спокойно можем заставить работать функцию inject даже в компонентах и директивах: Правда, выглядит это совершенно неюзабельно. Да и использование приватных функций Angular тоже не входит в лучшие практики. Поэтому не советую заниматься подобными вещами. InjectFlags — это аналог модификаторов Optional, Self, SkipSelf и Host. Используются в функциях inject и Injector.get. Документация и здесь не подвела — ее почти нет: Человек знающий сразу увидит здесь битовые маски. Этот же enum можно представить немного в другом виде: Вот так можно получить поток событий роутера, не беспокоясь о том, что модуль роутинга не подключен: Выглядит просто. А на деле — еще и безопасно, без неожиданных падений и лишних событий. Комбинацию флагов можно использовать при проверке, что модуль импортировался один раз. А комбинируются они при помощи побитового ИЛИ: Значение нужного бита получается с помощью побитового И: *SansProviders — сокращение для базовых интерфейсов обычных провайдеров ValueSansProvider, ExistingSansProvider, StaticClassSansProvider, ConstructorSansProvider, FactorySansProvider, ClassSansProvider. Tree shakable сервисы — это специальный способ сказать компилятору, что сервис не нужно включать в сборку, если он нигде не используется. При этом сервис не указывается в модуле, скорее наоборот — модуль указывается в сервисе: Как мы видим из примера, в проперти providedIn указан модуль. Это работает точно так же, как и следующий пример: providedIn также может содержать специальные значения: 'root', 'platform' и 'any'. Это достаточно хорошо описано в документации, но там вообще ничего не сказано о возможности использования фабрик (я нашел небольшое упоминание в одном из гайдов). Но если мы посетим исходники, то увидим, что мы можем использовать не только фабрики, но и все существующие способы провайдинга — useFactory, useValue, useExisting и т. д. Самый полезный, по моему мнению, способ использования фабрики в tree shakable сервисах выглядит так: Плюсы такого определения сервиса: Исключено случайное использование сервиса. Для работы с ним необходимо импортировать модуль сервиса. Самому модулю не нужно выделять статические методы forRoot и forChild. Гарантировано создание одного экземпляра сервиса. С остальными способами определения не все так очевидно. Я могу предположить, что это поможет при использовании внешних библиотек, в которых еще и отсутствует типизация. Например: В этом случае по токену JqueryInstance мы будем получать инстанс jQuery. Для остальных типов провайдеров я предлагаю придумать use-кейсы вам самим. Буду рад, если вы поделитесь ими в комментариях. В документации перечислены все существующие способы взаимодействия компонент и директив между собой: Input binding with a setter, ngOnChanges. Child events (outputs). Template variables. View/parent queries. Общий сервис. Но ни слова не сказано о том, что дочерняя директива/компонент совершенно спокойно может получить инстанс родителя через DI. UPD: нашлась все таки ссылочка на документацию, где описывается этот способ. На примере видно, что дочерняя директива получает инстанс компонента родителя, упрощая их взаимодействие. Обрабатывая клик по хостовому элементу, директива может напрямую поменять значение родительского компонента. Использование любого другого способа было бы как минимум более многословным. Но почему это возможно? Ответ может быть очень большим, и он явно выходит за рамки этой статьи. Когда-нибудь я напишу об этом более подробно. А пока предлагаю вам прочитать об иерархии инжекторов и ElementInjector (именно в таком порядке). Как я уже говорил, Angular — очень большой фреймворк. И я уверен, что в его исходниках можно найти намного больше интересных возможностей. Своими находками я всегда делюсь в своем Твиттере. Например, советы по Angular вы можете найти по хэштегу #AngularTip. А перевод самых интересных твитов — по хэштегу #AngularTipRus! Буду рад, если вы поделитесь своими наблюдениями и советами со мной и сообществом. Спасибо за внимание! Я вспомнил еще 2 статьи об Angular DI от @MarsiBarsi на русском языке. Пишите где угодно, предлагайте и давайте его пополнять!  Frontend-developer