TGViewer
Lil Functor Lil Functor @lilfunctor · 772 subscribers
Post #260 2.25K
В DI-фреймворке под названием ZIO можно автовайрить зависимости с помощью zio-magic, который ещё и встроят в версию 2.0. Код выглядит примерно так:

ZLayer.fromMagic[Env](
UsersRepository.live,
ClientsRepository.live,
RegistrationService.live
)


А дальше макрос на этапе компиляции выстроит граф зависимостей по входящим типам слоёв. Но частенько в приложении бывают классы, принимающие зависимости одного и того же типа. Допустим, grpc-клиенты к микросервисам BillingClient и NotificatorClient принимают в зависимости GrpcConfig. Содержимое этих конфигов очевидно разное, но на уровне типов этого не видно, поэтому нельзя понять, какой экземляр конфига к кому относится. Можно решить это ручным вайрингом:

ZLayer.fromMagic[Env](
Grpc.live,
Config.loadLayer[GrpcConfig]("billing") ++ ZLayer.environment[Has[Grpc]] >>> BillingClient.live,
Config.loadLayer[GrpcConfig]("notificator") ++ ZLayer.environment[Has[Grpc]] >>> NotificatorClient.live
)


Но мне это не нравится, потому что приходится внедрять куски ручного построения графа зависимостей в плоский список слоёв.

Так как вайринг происходит во время компиляции, различать зависимости нужно на уровне типов. Сразу пришла идея использовать тайп-теги: пометить слой зависимости каким-то тегом, и такой же тип затребовать в слое-получателе. Собственно, после некоторого пердолинга с компилятором было написано такое вот поделие: https://gist.github.com/poslegm/f252994a15453457e64d6498249928f3.

И с ним можно писать уже так:

ZLayer.fromMagic[Env](
Grpc.live,
Config.loadLayer[GrpcConfig]("billing").tagged[BillingClient.Service],
Config.loadLayer[GrpcConfig]("notificator").tagged[NotificatorClient.Service],
BillingClient.live.requireTagged[GrpcConfig, BillingClient.Service, Has[Grpc]],
NotificatorClient.live.requireTagged[GrpcConfig, NotificatorClient.Service, Has[Grpc]]
)


К сожалению не получилось придумать реализацию requireTagged, в которой не надо явно указывать компилятору тип "остатка" требуемых слоёв, кроме протегированного.

Зато теперь все зависимости укладываются в один плоский список, а zio-magic ругнётся, если не будет протегированной зависимости к какому-то слою.
More from @lilfunctor
  1. Apr 3, 2024Видео моего доклада «Как в Scala переложить JSON?» https://youtu.be/usp3Y0-VxwM?si=XwuewnR…
  2. Feb 27, 2024Как в Scala переложить JSON? В эту субботу буду выступать в Москве на Scala-митапе от Янде…
  3. Oct 22, 2023Конференция F[Scala] 🪜 Всем привет! Уже в следующую субботу в Москве пройдёт конференция…
  4. Feb 6, 2022Kit Langton, автор макроса для автовайринга ZLayer, отметился в любопытном пропозале на фо…
  5. Feb 1, 2022sbt версий 1.6.0 и 1.6.1 был с багом: при ошибке инициализации фреймворка для юнит тестов…
  6. Jan 30, 2022Uber публично задокументировал свой подход к организации микросервисов — Domain-Oriented M…
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 →