# auto-di
Spring-style dependency injection for Rust, backed by a global `inventory`
registry and async-safe initialization.
## Components and constructor injection
```rust
use std::sync::Arc;
use auto_di::{repository, service};
trait Users: Send + Sync {}
#[repository(name = "postgres", primary)]
fn users() -> Arc<dyn Users> {
Arc::new(PostgresUsers)
}
#[service(eager, post_construct = "start", pre_destroy = "stop")]
impl UserService {
fn new(#[qualifier("postgres")] users: Arc<dyn Users>) -> Self {
Self { users }
}
async fn start(&self) {}
async fn stop(&self) {}
}
```
`#[component]`, `#[service]`, `#[repository]`, and `#[singleton]` share these
options:
- `name = "..."`
- `primary`
- `scope = "singleton" | "prototype" | "request"`
- `eager`
- `profile = "development"`
- `condition = "ENV_KEY"` or `condition = "ENV_KEY=value"`
- `post_construct = "async_method"`
- `pre_destroy = "async_method"`
Constructors accept `Arc<T>`, `Option<Arc<T>>`, `Vec<Arc<T>>`, `Provider<T>`,
and `Lazy<T>`. Both sync and async constructors are supported.
## Configuration beans
```rust
#[derive(Default)]
struct Beans;
#[configuration]
impl Beans {
#[bean]
fn config(&self) -> Config { Config::default() }
#[bean(name = "main", primary)]
async fn database(&self, config: Arc<Config>) -> Database {
Database::connect(&config).await
}
}
```
## Environment properties
```rust
#[configuration_properties("database")]
struct DatabaseProperties {
url: String, // DATABASE_URL
pool_size: usize, // DATABASE_POOL_SIZE
}
```
## Application and request scopes
```rust
#[application]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let service = auto_di::resolve::<UserService>().await?;
Ok(())
}
let request = auto_di::global_container()?.request_context();
let bean = request.resolve::<RequestBean>().await?;
```
Active profiles come from comma-separated `APP_PROFILES`, or can be selected
explicitly with `Container::with_profiles(...)`.