rust_dicore/lib.rs
1//! LRDI — Rust Dependency Injection Framework
2//!
3//! A dependency injection container for Rust inspired by
4//! Microsoft.Extensions.DependencyInjection (MEDI).
5//!
6//! # Quick start
7//!
8//! ```rust
9//! use rust_dicore::*;
10//! use std::sync::Arc;
11//!
12//! struct Logger(String);
13//! struct Worker { log: Arc<Logger> }
14//!
15//! let provider = ServiceCollection::new()
16//! .singleton(|_| Arc::new(Logger("INFO".into())))
17//! .singleton(|_| Arc::new(Worker { log: Arc::new(Logger("INFO".into())) }))
18//! .build()
19//! .unwrap();
20//!
21//! let logger: Arc<Logger> = provider.get::<Logger>();
22//! ```
23//!
24//! # Features
25//!
26//! - **Three lifetimes**: Singleton, Scoped, Transient
27//! - **Keyed services**: multiple instances of the same type, distinguished by key
28//! - **Constructor injection**: `#[derive(Inject)]` on structs
29//! - **Compile-time module scanning**: `#[rust_dicore::module]` collects service registrations
30//! - **Cross-DLL support**: named service registry for cdylib plugins
31//!
32//! # Crate layout
33//!
34//! | Module | Description |
35//! |--------|-------------|
36//! | [`ServiceCollection`] | Register services with a builder API |
37//! | [`ServiceProvider`] | The root DI container |
38//! | [`Scope`] / [`ServiceScope`] | Scoped container (one per scope) |
39//! | [`IServiceResolver`] | Resolution trait (implemented by `ServiceProvider` & `Scope`) |
40//! | [`ServiceProviderWrapper`] | Child-first layered container |
41//! | [`ServiceLifetime`] | Enum: Singleton, Scoped, Transient |
42//! | [`IServiceLocator`] / [`ServiceLocatorBridge`] | Cross-DLL / plugin integration |
43//! | [`RdiError`] | Error types |
44//!
45//! # Proc-macros
46//!
47//! - `#[derive(Inject)]` — auto-generates constructor injection code
48//! - `#[rust_dicore::module]` — compile-time module scanning
49//! - `rust_dicore::inject!(...)` — declare services inside `#[rust_dicore::module]`
50
51pub mod bridge;
52pub mod collection;
53pub mod descriptor;
54pub mod entry;
55pub mod error;
56pub mod lifetime;
57pub mod provider;
58pub mod registration;
59pub mod scope;
60pub mod service_locator;
61pub mod store;
62pub mod wrapper;
63
64// ── Core types (MEDI-inspired naming) ──
65
66/// Service collection — register services, then call `.build()`.
67///
68/// Analogous to `IServiceCollection` in Microsoft.Extensions.DependencyInjection.
69pub use collection::ServiceCollection;
70
71/// Built service provider — the root DI container (read-only after build).
72///
73/// Analogous to `IServiceProvider` in MEDI.
74pub use provider::ServiceProvider;
75
76/// Service descriptor containing registration metadata.
77pub use descriptor::ServiceDescriptor;
78
79/// Service lifetime enum: [`Singleton`](ServiceLifetime::Singleton),
80/// [`Scoped`](ServiceLifetime::Scoped), [`Transient`](ServiceLifetime::Transient).
81pub use lifetime::ServiceLifetime;
82
83/// Core resolution trait. Both [`ServiceProvider`] and [`Scope`] implement this.
84pub use entry::IServiceResolver;
85
86/// A scoped service provider — created via [`ServiceProvider::create_scope`].
87///
88/// Analogous to `IServiceScope` in MEDI.
89pub use scope::Scope;
90
91/// Alias for [`Scope`] with MEDI-inspired naming (`IServiceScope`).
92pub use scope::Scope as ServiceScope;
93
94/// Internal types used by the container.
95pub use entry::{ServiceEntry, ServiceFactory};
96
97/// Wrapper combining child + root provider with child-first resolution.
98pub use wrapper::ServiceProviderWrapper;
99
100// ── Plugin / cross-DLL support ──
101
102/// Trait for service location (type-based + named) — used for external integration.
103pub use service_locator::IServiceLocator;
104
105/// Trait for named service registration.
106pub use service_locator::INamedRegistrar;
107
108/// Adapts RDI types to [`IServiceLocator`].
109pub use bridge::{RdiProvider, ServiceLocatorBridge};
110
111// ── Error types ──
112
113/// Error types returned from service resolution.
114pub use error::RdiError;
115
116// ── Runtime registration ──
117
118pub use registration::ServiceRegistration;
119
120/// Re-export of `inventory` so that `#[rust_dicore::inject]` generated code
121/// can call `rust_dicore::inventory::submit!` without requiring downstream crates
122/// to add `inventory` to their own `Cargo.toml`.
123#[doc(hidden)]
124pub use inventory;
125
126// ── Proc-macros ──
127
128// Note: `inject_attr` is the attribute macro; `inject` is the declare macro
129// used inside `#[rust_dicore::module]`. Users write both as `#[rust_dicore::inject(...)]`
130// and `rust_dicore::inject!(...)` respectively.
131pub use rust_dicore_macros::{inject, inject_attr, module, Inject};