TGViewer
Kotlin Kotlin @kotlin_lib · 2.05K subscribers
Post #708 658
🔮 Убийца бойлерплейта: Встречайте Context Parameters (Kotlin 2.x)

Мы так привыкли к Dependency Injection (Dagger/Hilt/Koin), что перестали замечать, как он раздувает наш код.
Сценарий из жизни: вам нужно залогировать событие глубоко в слое бизнес-логики. Вы берете интерфейс Logger и прокидываете его через конструкторы пяти промежуточных классов, хотя он нужен только в одном методе на самом дне.

В Kotlin 2.1+ (KEEP-367) активно допиливают киллер-фичу, которая меняет правила игры - Context Parameters.

Историческая справка: Если вы помните экспериментальные Context Receivers (синтаксис context(Logger)), забудьте их. JetBrains официально задепрекейтили их в версии 2.0.20, заменив на более строгие и читаемые Context Parameters.

Как это выглядит теперь?

Допустим, у нас есть TransactionScope и Logger. Мы не хотим инжектить их в классы-прослойки, мы хотим потребовать их наличие в функции неявно.


// Новая магия: context(...) перед функцией с явными именами переменных
context(logger: Logger, tx: TransactionScope)
fun deleteUser(userId: String) {
logger.log("Deleting user $userId")

tx.execute {
// ... логика удаления в БД
}
}



В чем отличие от обычных параметров?
При вызове функции deleteUser вам не нужно передавать эти параметры руками! Компилятор сам найдет их в текущем скоупе (scope) и подставит под капотом.


class UserUseCase(
private val logger: Logger,
private val tx: TransactionScope
) {
fun execute() {
// Вводим зависимости в область видимости
with(logger) {
with(tx) {
// Вызываем функцию БЕЗ передачи логгера и транзакции!
// Компилятор сам слинкует их из контекста.
deleteUser("user_123")
}
}
}
}



(На практике вы настроите скоуп один раз на самом верхнем уровне — например, в базовой ViewModel или HTTP-хендлере Ktor — и вся вложенная цепочка вызовов получит к ним доступ).

Почему это круто для архитектуры?

1. Чистые сигнатуры: Бизнес-функции принимают только бизнес-аргументы (например, userId: String). Вся техническая инфраструктура (логирование, аналитика, права доступа, транзакции) выносится за скобки.
2. Читаемость (в отличие от старых Receivers): Раньше методы из контекста вызывались неявно (просто log()), и в большом классе было невозможно понять, откуда пришел этот метод. Теперь у нас есть жесткое имя: logger.log().
3. Идеально для Cross-cutting concerns: Это элегантное решение для сквозного функционала, который не должен загрязнять доменную модель.

⚠️ Правило Сеньора:
Context Parameters - это не замена конструкторному DI.
Если классу нужен UserRepository для выполнения всех его основных задач, передавайте его в конструктор. Используйте context(...) только для тех сущностей, которые меняются в зависимости от среды выполнения (call chain), или для утилитарных инструментов (например, AnalyticsScope).

✍️ @kotlin_lib
  • 👍 4
  • 🔥 2
More from @kotlin_lib
  1. Aug 26, 2026🚧 Ваш Mutex тормозит корутины. Как перестать лочить и начать жить Вы пишете многопоточный…
  2. Jul 25, 2026🚀 Подборка полезных IT каналов в Max Системное администрирование, DevOps 📌 https://max.r…
  3. Jul 1, 2026🌪 Ваша дата в опасности: flatMapConcat vs Merge vs Latest Вам нужно взять поток ID-шников…
  4. Jun 24, 2026🤖 Android-приложение — это не только красивый экран. За ним стоят работа с внешним API, з…
  5. Jun 3, 2026Яндекс обновил Yandex Mobile Ads SDK для монетизации мобильных приложений — и это интересн…
  6. Jun 3, 2026ktorgen - Kotlin + KSP + Ktor Client Code Generator Легкий процессор Kotlin KSP для генера…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →