Airframe

Airframe is a collection of lightweight libraries useful for building full-fledged applications in Scala.

For advanced users we also provide dependency injection (DI) library tailored to Scala. Dependency injection (Wikipedia) is a design pattern for simplifying object instantiation; Instead of enumerating necessary objects (dependencies) within constructor arguments, DI framework builds objects on your behalf. While Google’s Guice is designed for injecting Java objects (e.g., using class constructors or providers), Airframe redesigned it for Scala to so that we can enjoy the flexibilities of Scala traits and DI at the same time.

Resources

Getting Started

Latest version

Airframe is available for Scala 2.13, 2.12, 2.11, and Scala.js. For Scala 2.12.6 or later, Java 9 and 10 are also supported.

Usage

Airframe is a collection of Scala libraries. You can include one or more of them to your dependencies:

build.sbt

val AIRFRAME_VERSION="(version)"

# For Scala 2.11, 2.12, and 2.13
libraryDependencies ++= Seq(
  "org.wvlet.airframe" %% "airframe"         % AIRFRAME_VERSION, // Dependency injection
  "org.wvlet.airframe" %% "airframe-codec"   % AIRFRAME_VERSION, // MessagePack-based schema-on-read transcoder
  "org.wvlet.airframe" %% "airframe-config"  % AIRFRAME_VERSION, // YAML-based configuration
  "org.wvlet.airframe" %% "airframe-jmx"     % AIRFRAME_VERSION, // JMX monitoring
  "org.wvlet.airframe" %% "airframe-jdbc"    % AIRFRAME_VERSION, // JDBC connection pool
  "org.wvlet.airframe" %% "airframe-log"     % AIRFRAME_VERSION, // Logging
  "org.wvlet.airframe" %% "airframe-metrics" % AIRFRAME_VERSION, // Metrics units
  "org.wvlet.airframe" %% "airframe-opts"    % AIRFRAME_VERSION, // Command-line option parser
  "org.wvlet.airframe" %% "airframe-surface" % AIRFRAME_VERSION, // Object surface inspector
  "org.wvlet.airframe" %% "airframe-tablet"  % AIRFRAME_VERSION  // Table data reader/writer
)

# For Scala.js, the following libraries can be used:
libraryDependencies ++= Seq(
  "org.wvlet.airframe" %%% "airframe"         % AIRFRAME_VERSION, // Dependency injection
  "org.wvlet.airframe" %%% "airframe-log"     % AIRFRAME_VERSION, // Logging
  "org.wvlet.airframe" %%% "airframe-metrics" % AIRFRAME_VERSION, // Metrics units
  "org.wvlet.airframe" %%% "airframe-surface" % AIRFRAME_VERSION  // Object surface inspector
)

Dependency Injection with Airframe

With Airframe, your Scala programming can be greatly simplified:

First, bind objects to your code with bind[X]:

import wvlet.airframe._

trait App {
  val x = bind[X]
  val y = bind[Y]
  val z = bind[Z]
  // Do something with x, y, and z
}

Next, design the object bindings:

val design: Design =
  newDesign
    .bind[X].toInstance(new X)  // Bind type X to a concrete instance
    .bind[Y].toSingleton        // Bind type Y to a singleton object
    .bind[Z].to[ZImpl]          // Bind type Z to a singletone of ZImpl instance

Then build an instance and use it:

design.build[App]{ app =>
  // Do something with App
}

Airframe builds an instance of App based on the binding rules specified in the design object. That means when writing applications, you only need to care about how to use objects (bind), rather than how to build them, because design objects already knows how to provide necessary objects to build your classes.

This separation of object bindings and their design (assembly) is useful for reducing code duplications between production and test codes. For example, compare writing new App(new X, new Y(...), new Z(...), ...) in both of your main and test codes, and just calling session.build[App]. Airframe can integrate the flexibility of Scala traits and dependency injection (DI). Mixing traits is far easier than calling object constructors. This is because traits can be combined in an arbitrary order. So you no longer need to remember the order of the constructor arguments.

Airframe DI Features

Major features of Airframe DI are as follows:

  • Simple usage
    • Just import wvlet.airframe._ and do the above three steps to start DI in Scala.
  • Airframe can create objects from Scala traits.
  • Design objects are immutable. You can create a new design safely based on an existing design.
  • Supports all possible binding types: constructor, instance, provider, singleton bindings.
  • Built-in life cycle management of objects (init, shutdown, etc.) through sessions.
  • Scala macro based binding generation, which helps binding objects to your code.
  • Scala 2.11, 2.12, 2.13, and Scala.js support.
  • Java9/10 support.

What’s Next?

See Documentation for further details.

Scala

Airframe is completely written in Scala

SBT

Airframe uses SBT and other sbt plugins to generate microsites easily