Skip to content

ornamental/monadic-injection

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Compile-Time Dependency Injection in Monadic Context

Applications frequently require values and resources created in monadic context to be used as dependencies in other components which in their turn are allocated in such context.

This is a shapeless-based tool allowing one to organize the creation of dependencies and their eventual usage in an effectful computation.

Example (@@-tagged types are provied by supertagged):

final case class Configuration(
  port: Int @@ "service-port", 
  dataSourceUrl: URL @@ "data-source",
  pollingInterval: FiniteInterval @@ "data-source")

trait DataSourceClient[F[_]] { ... }

class DataSourceClientImpl[F[_]: Concurrent] private (
  sttpBackend: SttpBackend[F, Any],
  dataSourceUrl: URL,
  pollingInterval: FiniteInterval,
  requestCounter: Ref[F, RequestCounter]) extends DataSourceClient[F] { ... }

object DataSourceClientImpl {

  def apply[F[_]: Concurrent](
      sttpBackend: SttpBackend[F, Any],
      dataSourceUrl: URL @@ "data-source",
      pollingInterval: FiniteInterval @@ "data-source"): F[DataSourceClientImpl[F]] =
    Ref[F].of(RequestCounter.empty) >>=
      (new DataSourceClientImpl(sttpBackend, dataSourceUrl, pollingInterval, _))
}

object Service {

  def run[F[_]: Concurrent](
      port: Int @@ "service-port",
      dataSourceClient: DataSourceClient[F]): F[Nothing] = { ... }
}

object Main {

  private val configuration = Configuration(
    port = @@["service-port"](9000),
    dataSourceUrl = @@["data-source"](new URL("https://data-source:80")),
    pollingInterval = @@["data-source"](10.seconds))

  def run[F[_]: Concurrent]: F[Unit] =
    InjectionContext[F]()
      .provideFields(configuration)
      .provideR(AsyncHttpClientCatsBackend.resource[F]())
      .addF(DataSourceClientImpl[F](_, _, _))
      .use(Service.run(_, _))
}

Releases

No releases published

Packages

No packages published

Languages