Android-разработчик представил KSP-генератор DI для многомодульных проектов
Евгений, Android-разработчик, представил новый подход к внедрению зависимостей на основе KSP. Инструмент под названием KoGen позволяет создавать независимые DI-контейнеры для каждого модуля без ручного кода и бойлерплейта.
В мире Android-разработки Dependency Injection (DI) давно стал стандартом, но настройка многомодульных проектов часто превращается в источник боли. Евгений, Android-разработчик из Казахстана, столкнувшись с этой проблемой при работе над очередным многомодульным приложением, решил создать собственный DI-фреймворк. Его инструмент, получивший название KoGen, использует Kotlin Symbol Processing (KSP) для генерации кода, который связывает зависимости автоматически. Основная цель — добиться полной независимости feature-модулей, чтобы каждый из них мог работать со своим собственным DI-контейнером без необходимости создавать общий компонент в главном модуле приложения. Разработчик представил первую версию библиотеки, которая уже прошла проверку на реальных проектах и готова к использованию.
Ключевая проблема, которую решает KoGen, — отсутствие точки входа для инициализации DI в библиотеках, которые не имеют класса Application. Традиционные фреймворки, такие как Dagger, Hilt и Koin, стартуют из Application, что делает их непригодными для изолированных модулей. Кроме того, попытка запустить несколько DI-контейнеров в одном приложении обычно приводит к конфликтам и крэшам. KoGen обходит эти ограничения, предоставляя каждому модулю собственную точку входа через аннотацию @KoGenComponent. Для классов, помеченных этой аннотацией, KSP-процессор генерирует enum-справочник и фабрику, которые позволяют получать экземпляры по типу или интерфейсу. Это позволяет избежать ручного написания кода для связывания зависимостей.
Технически KoGen генерирует enum KoGenComponentsImpl, где каждому классу соответствует элемент с указанием признака singleton. Фабрика KoGenComponentsFactoryImpl содержит карту соответствий между классами и элементами enum. В первой версии разработчик использовал сравнение типов по строковым именам, что приводило к ошибкам при обфускации R8/ProGuard. После переработки сравнение стало выполняться по идентичности Class-объектов, что сделало инструмент устойчивым к обфускации. Важной особенностью является поддержка библиотек, таких как Room и Retrofit, где реализации интерфейсов генерируются автоматически. Для таких случаев предусмотрен отдельный механизм, позволяющий явно указать, как создавать экземпляр, даже если нельзя вызвать конструктор напрямую.
Разработчик отмечает, что существующие решения, такие как Dagger с Subcomponents или Koin с изолированными инстансами, частично решают проблему независимости модулей, но не полностью. Dagger по-прежнему требует создания общего компонента в app-модуле, что связывает все модули неявными зависимостями. Koin, в свою очередь, навязывает использование своего фреймворка всем потребителям библиотеки, что неприемлемо для переиспользуемых библиотек. KoGen, напротив, не требует от других проектов перехода на новый DI-фреймворк: библиотека может быть подключена к любому проекту, и её внутренние зависимости будут управляться собственным контейнером, не мешая основному приложению. Это делает инструмент особенно привлекательным для создания SDK и библиотек, которые должны работать в разных средах.
Для российского рынка и русскоязычного сообщества разработчиков появление такого инструмента может стать значимым событием. Многие компании сталкиваются с проблемой поддержки многомодульных проектов, и KoGen предлагает простое решение, которое сокращает количество ручного кода и уменьшает вероятность ошибок на этапе выполнения. Инструмент также поддерживает проверку графа зависимостей на этапе компиляции, что позволяет выявлять ошибки конфигурации до выпуска приложения. Это особенно важно для крупных проектов, где отладка DI в рантайме может быть крайне трудоёмкой. Пока неизвестно, планирует ли автор открыть исходный код, но уже сейчас он демонстрирует работоспособность подхода на практике.
В планах развития KoGen — поддержка ViewModel, что расширит его применимость для архитектур на основе MVVM. Разработчик также рассматривает возможность добавления других функций, таких как поддержка скоупов и кастомных фабрик. Однако остаются открытые вопросы: как инструмент поведёт себя в проектах с очень сложными графами зависимостей, и насколько просто его интегрировать в существующие проекты. Пока KoGen находится на ранней стадии, но его подход к генерации кода через KSP выглядит многообещающим. Возможно, в будущем он станет достойной альтернативой классическим DI-фреймворкам, особенно для тех, кто ценит чистоту архитектуры и независимость модулей. Сообщество Android-разработчиков с интересом ждёт новых публикаций и возможного релиза библиотеки в открытом доступе.