Library Alternatives#

As always, developers should consider carefully whether (1) DI is the correct pattern for their needs, whether (2) the scale of the problem requires a DI framework, and (3) which DI framework to use.

For (3), dilib comes with a core set of functionality that may be more suitable for some problems. This document motivates why a new DI framework was built and highlights some differences with existing DI frameworks, but it’s not meant to detract from the hard work and innovation of these other libraries.

pinject#

Advantages of dilib over pinject:

  • It has been archived by the owner on Jan 10, 2023

  • Focus on simplicity.

    • The syntax of foo = dilib.Object("a") looks more like regular dataclasses than bind("foo", to_instance="a").

    • Child configs look like just another field on the config.

  • Getting objects is via names rather than classes.

    • In pinject, the equivalent of container attr access takes a class (like Car) rather than a config addressess.

  • No implicit wiring: No assumptions are made about aligning arg names with config params.

    • pinject does have an explicit mode, but the framework’s default state is implicit.

    • The explicit wiring in dilib configs obviates the need for complications like inject decorators and annotations.

  • Minimal or no pollution of objects: Objects are not aware of the DI framework.

    • The only exception in dilib is the optional easier syntax mode. In pinject, on the other hand, one is required to decorate with @pinject.inject() in some circumstances.

dependency-injector#

Advantages of dilib over dependency-injector:

  • dilib highly encourages static containers over dynamic ones by not including dynamic functionality at all

  • Separation between “config” and “container” (dependency-injector conflates the two)

  • Easy-to-use perturbing with simple config.x = new_value syntax

  • Easier to nest configs, with same syntax as defining specs

  • Child configs are strongly typed instead of relying on DependenciesContainer stub (which enables IDE auto-complete and type checking)

  • No separation between configuration and specs: they have the same syntax and static typing capability

  • Easier-to-use global input configuration

  • Written in native Python for more transparency

injector#

injector

TODO