noema 0.3.0

Noema IOC and DI framework for Rust
Documentation

NOEMA

Noema is a Rust toolkit for Dependency Injection (DI) and Inversion of Control (IoC) built around a single, extensible container.
It helps you go from simple service resolution to higher-level patterns like Mediator (Sender), Event Dispatching (Dispatcher), Keyed services, and more—mostly through compile-time wiring powered by macros and trait-based registries.

Noema is designed for concurrent (multi-threaded) applications. In most cases you will resolve dependencies as Arc<T> to keep everything thread-safe and shareable. Some APIs may also allow &T (e.g. reference resolving), but Arc<T> is the default and recommended approach.


Core idea: one container

Noema uses one dependency container that can grow with your project—even across multiple crates—while still enabling different lifecycles depending on the feature/pattern you’re using.

3 lifecycles (“times”)

  • Runtime

    • Registries can grow and be configured during runtime.
  • Once Runtime

    • One-time initialization during runtime (register once, then use).
  • Compile-time

    • Wiring is done through traits + static registries (fast resolution, predictable setup).

In practice, some features are purely compile-time, while others require runtime initialization (for example, the dispatcher).


Features

Noema is feature-flag driven. Enable only what you need.

Services (services)

Classic DI building blocks: register and resolve services.

Two dependency styles:

  • Components: singleton-style dependencies (the same instance is reused)
  • Factories / Providers: create a new instance per resolution

This is primarily compile-time oriented via trait-based resolvers and macros.


Sender / Mediator (sender)

A Mediator-style workflow similar to MediatR:

  • Define an Input (command/query)
  • Implement an InputHandler
  • send(input) returns the handler output

This is designed to be compile-time wired and integrates naturally with DI.


Dispatcher / Events (dispatcher)

A runtime event dispatcher with multiple listeners per event:

  • Define events (with metadata like name and description)
  • Register multiple EventHandler implementations
  • Dispatch events to listeners

Because it uses background tasks and internal setup, it requires an initialization step (e.g. dispatcher_init) and is runtime focused.


Configurations (configurations)

A simple way to manage user-defined mutable configuration, configured once and then injected like any other dependency.

  • Define a config type implementing Configurable
  • Noema configures it once during initialization
  • Then you can resolve it through the container

This is typically compile-time oriented.


Items Collections (items_collections)

Extensible “enum-like” collections that scale beyond typical enums:

  • Define a collection type
  • Register multiple items (via structs/macros)
  • Resolve/consume the collection as a dependency

This feature is powerful but requires modeling the collection carefully.
Lifecycle: Once Runtime.


Keyed Services (keyed_services)

Strategy-like extensibility:

  • Multiple implementations of a service trait
  • Select an implementation using a key
  • Typically factory-based (not singleton-oriented)

Lifecycle: Once Runtime.


Status / Notes

  • Rust-first, macro-assisted ergonomics
  • Concurrency-oriented (Arc<T>-based dependency sharing)
  • Feature-flag driven: enable only what your project needs

License

(Add your license here)