#![allow(warnings)]
use injectable_rs::*;
use std::sync::Arc;
#[injectable]
#[derive(Default, Clone, Debug)]
pub struct Config;
#[injectable]
#[derive(Default, Clone, Debug)]
pub struct Database;
#[injectable]
#[derive(Default, Clone, Debug)]
pub struct Cache;
#[injectable]
#[derive(Debug)]
pub struct UserRepository {
db: Inject<Database>,
}
impl UserRepository {
pub fn find_user(&self, id: u32) -> String {
format!("User#{id} found via database")
}
}
#[injectable]
#[derive(Debug)]
pub struct UserService {
repo: Inject<UserRepository>,
cache: Inject<Cache>,
}
impl UserService {
pub fn get_user(&self, id: u32) -> String {
self.repo.find_user(id)
}
}
#[injectable]
#[derive(Debug)]
pub struct OwnedService {
#[injectable(inject)]
db: Arc<Database>,
#[injectable(inject)]
cache: Arc<Cache>,
}
#[injectable]
#[derive(Debug)]
pub struct MixedService {
db: Inject<Database>, #[injectable(inject)]
config: Arc<Config>,
}
#[derive(Debug)]
pub struct ConfigWithPort {
pub db: Inject<Database>,
pub port: u16,
pub host: String,
}
#[injectable]
impl ConfigWithPort {
#[injectable(ctor)]
fn new(db: Inject<Database>) -> Self {
Self {
db,
port: 0,
host: String::new(),
}
}
}
#[derive(Debug)]
pub struct PartialInjectService {
db: Inject<Database>,
name: String,
cache: Inject<Cache>,
}
#[injectable]
impl PartialInjectService {
#[injectable(ctor)]
fn new(db: Inject<Database>, cache: Inject<Cache>) -> Self {
Self {
db,
name: String::new(),
cache,
}
}
}
#[tokio::main]
async fn main() {
println!("=== Basic Field Injection Example ===\n");
let container = Container::builder()
.build()
.await
.expect("container should build");
let db = container
.resolve::<Database>()
.await
.expect("resolve Database");
println!("Resolved Database: {db:?}");
let repo = container
.resolve::<UserRepository>()
.await
.expect("resolve UserRepository");
println!("\nResolved UserRepository");
println!(" {}", repo.find_user(42));
let service = container
.resolve::<UserService>()
.await
.expect("resolve UserService");
println!("\nResolved UserService");
println!(" {}", service.get_user(1));
let owned = container
.resolve::<OwnedService>()
.await
.expect("resolve OwnedService");
println!("\nResolved OwnedService: {owned:?}");
let mixed = container
.resolve::<MixedService>()
.await
.expect("resolve MixedService");
println!("\nResolved MixedService: {mixed:?}");
println!("\n--- #[injectable(inject)] in #[injectable(default)] struct ---");
let config = container
.resolve::<ConfigWithPort>()
.await
.expect("resolve ConfigWithPort");
println!("ConfigWithPort (default + #[injectable(inject)] on db): {config:?}");
println!(" db field was INJECTED (not defaulted)");
println!(" port field was defaulted: {}", config.port);
println!(" host field was defaulted: {:?}", config.host);
println!("\n--- Non-injectable field via constructor ---");
let partial = container
.resolve::<PartialInjectService>()
.await
.expect("resolve PartialInjectService");
println!("PartialInjectService: {partial:?}");
println!(" db field was INJECTED via Inject<T>");
println!(" name field was set by constructor: {:?}", partial.name);
println!(" cache field was INJECTED via Inject<T>");
println!("\n--- Destructuring Pattern ---");
let Inject(_db_arc) = Inject::<Database>::extract(container.context())
.await
.expect("extract Database");
println!("Destructured Inject<Database> into Arc<Database>");
println!("\n--- Resolving Multiple Types ---");
let config = container.resolve::<Config>().await.expect("resolve Config");
let cache = container.resolve::<Cache>().await.expect("resolve Cache");
println!("Config: {config:?}");
println!("Cache: {cache:?}");
println!("\n=== Example Complete ===");
}