Кодогенерация#

Кодогенерация позволяет автоматизировать рутинные операции.

DI-процессор#

Автоматизирует работу с инъекциями зависимостей в GsSession.

Отвечает за генерацию:

  • Session-extensions
    Файл ${Cls}SessionGen.kt добавляет три метода к GsSession:
    getCls(), destroyCls(), recreateCls().

  • GlobalFactory.kt
    Для всех @GsBean создаётся объект-фабрика с thread-safe ConcurrentHashMap.
    Позволяет получить, пересоздать или обнулить singleton без DI-контейнера.

  • MainStorage.kt
    Минимальное потокобезопасное хранилище для глобальных бинов.

Примечание

При необходимости можно добавить произвольный DI-фреймворк, например Dagger / Hilt.

Ключевые аннотации#

Аннотация

Применяется к классу-бину

Жизненный цикл

Как вызывается

@GsPkgBean

Package-класс, работающий внутри GsSession

Создаётся и кешируется на время сессии

session.get<ИмяPkg>() (сгенерированный extension)

@GsApiBean

API-класс поверх Room

То же, что и @GsPkgBean

session.get<ИмяApi>()

@GsBean

Глобальный компонент (парсер, crypto-утилита и др.)

Singleton всего процесса

GlobalFactory.get<Имя>()

Пример#

@GsApiBean
class UserApi(ctx: ApiBeanContext)
    : DbBaseApiGen<User, UserDao, AppDb>(ctx) { /* ... */ }

@GsPkgBean
class SyncPkg(ctx: PkgBeanContext) : DbPkg2(ctx)

@GsBean
class CryptoUtil   // не зависит от сессии


// Работаем в State или другом серверном коде

val api    = session.getUserApi()     // сгенерировано
val pkg    = session.getSyncPkg()
val crypto = GlobalFactory.getCryptoUtil()

Подключение к проекту DI#

plugins {
    id("com.google.devtools.ksp") version "1.9.22-1.0.17"
}

dependencies {
    ksp(project(":di-processor"))
}

Правила создания#

  • Конструктор аннотированного класса должен принимать ровно один аргумент-контекст (ApiBeanContext или PkgBeanContext).

  • Для singleton с побочным состоянием необходимо использовать @GsBean и управлять жизненным циклом вручную через GlobalFactory.

Диагностика ошибок#

Сгенерированный код лежит в $buildDir/generated/ksp/.../di/.
При любой проблеме (цикличность, нарушение областей) KSP прерывает компиляцию и выводит понятное сообщение вида:
Cycle detected: a.b.C -> x.y.D -> a.b.C.

Исправьте зависимости — Gradle пересоберётся без перезапуска IDE.

Room-процессор#

Отвечает за генерацию:

  • базы данных;

  • Dao.

Подключение к проекту Room#

dependencies {
    ksp(libs.androidx.room.compiler)
}

Результат кодогенерации#

Получается один JAR < 1 МБ, не требующий рефлексии и не трогающий рантайм,
что позволяет легко обфусцировать код.