distage: Staged Dependency Injection
distage
is a pragmatic module system for functional Scala, it aims to combine simplicity and expressivity of pure FP with the flexibility and extreme late-binding that’s traditionally associated with object-oriented dependency injection frameworks, such as Guice.
distage
is suitable for structuring applications in Tagless Final Style, with ZIO Environment, or in imperative Scala style.
Why use distage?
- Faster applications and tests:
distage
guarantees that no unnecessary instantiations will happen during your tests or application startup. - Quick failure detection:
distage
performs all the integration checks for your application and tests even before any instantiations happened. - Simple tests:
distage
eliminates all the hard work of setting up your test environments, especially configurable ones. - Better integration tests:
distage
provides you great memoization support for your tests so you may reuse expensive resources (like database connections) across multiple integration tests, gaining performance and without sacrificing correctness. - Simple development workflow: distage-framework module allows you to develop Role-Based Applications – a fusion of Microservices and Monoliths. You may run all your services in one process for development purposes (and even switch to mock implementations with a single commandline argument).
- Fast compile times and low mental overhead: Unlike fully compile-time DIs,
distage
does not impose a compile time penalty.distage
extensions are simple to write and do not require type-level programming. - Simple debugging:
distage
provides you important insights about your application and allows you to introspect and modify it on the fly, before any instantiations happen. - High Correctness:
distage
supports resources and lifecycle natively and guarantees proper cleanups even when something went wrong. - No reflection:
distage
generates all constructors and type info at compile-time and does not use Scala reflection. As such, it’s compatible with Graal Native Image and (soon) Scala.js. - Non-invasive:
distage
is designed to not impact the way your Scala code is written. It just removes all the initialization boilerplate. You don’t need to learn magic tricks to write components in a distage application.
distage
is recommended by industry leaders:
Given its native support for type classes and higher-kinded types – both features indispensable to functional programming – distage is one of the leading dependency injection libraries out there. Bonus points for being built by a wicked-smart team that contributes to ZIO!
-? John A. De Goes
FAQ
Q: How to pronounce distage
?
A: ‘Dee-stage’
Q: Isn’t it unsafe to use runtime dependency injection?
A: distage
is split into two stages, first a wiring plan
is calculated, only afterwards it is executed. This Plan
value can be tested for errors in an ordinary test suite ? if it is well-formed, the wiring will succeed at runtime. This test can also be performed at compile-time ? distage-framework
module contains macros for aborting compilation in case of erroneous wiring.