# 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**.

---

### Modules (`modules`)
A lightweight module system to structure applications:

- Group registrations/configuration into modules
- Initialize modules (including async init flows)
- Apply configuration centrally

Useful for modular monolith designs and larger codebases.

---

## 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)
