Skip to main content

Dependency Injection

The Exodus SDK uses the dependency-injection Inversion of Control Container (IoC) to instantiate and wire up all of its internals legos.

What an IoC Enables

IoC's are not pervasive in the JavaScript ecosystem, but are staples in other languages/ecosystems. They provide several benefits:

  • Loose coupling:
    • No hard dependencies between components, except on utility packages
    • Depend on interfaces rather than concrete implementations
    • Defer dependency resolution till runtime
  • Testing: test without mocking/monkeypatching
  • Scalability: no giant entrypoint file with manual instantiation of all nodes

Concretely, in the Exodus SDK, this enables:

  • The SDK to be platform-agnostic and accept adapters on each platform
  • Consumers to inject their own implementations of interfaces

Nodes in the IoC

Though the IoC is a flat tree of nodes of the shape { id, factory, dependencies }, we've also added a (lego) type field to enable useful pre-processing. Aside from the common node types: 'atom', 'module', 'api', and 'plugin', which correspond to legos, there are a few special ones:

atom-collection

An atom-collection is just an Object map for a group of atoms.

Examples

report

A report node is used by @exodus/headless to assemble a debug report in case of a crash, via exodus.reporting.export(). Each feature can implement a report node, which will be added to the debug report namespaced at the feature's id.

Examples

debug

A debug node is used by @exodus/headless to provide APIs at exodus.debug in dev mode only. This is useful for mocking things at runtime, e.g. geolocation or wallet addresses.

Examples

Preprocessors

Preprocessors are functions that run before the IoC container is built. They can be used to modify the IoC node list before dependencies are resolved, e.g. to add a node, modify a node's dependencies, or wrap a node's factory. For example, if you want to time all methods of all nodes in the IoC, you could write a preprocessor that wraps each node's factory in a timing function and warns when it exceeds a certain threshold.

More on preprocessors in dependency-preprocessors.