Перейти к основному содержанию
`Ctrl`+`K`

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

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

## 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 МБ, не требующий рефлексии и не трогающий рантайм,
что позволяет легко обфусцировать код.