#[injectable]Expand description
Unified DI attribute macro.
Applied to structs, impl blocks, traits, and functions depending on the sub-argument provided:
§On a struct (field injection)
ⓘ
#[injectable]
pub struct UserService {
db: Inject<Database>, // auto-injected
#[injectable(inject)]
pool: sqlx::SqlitePool, // requires annotation
}§On an impl block (constructor / lifecycle)
ⓘ
#[injectable]
impl UserService {
#[injectable(ctor)]
pub fn new(db: Inject<Database>) -> Self { Self { db } }
#[injectable(post_construct)]
async fn init(&self) -> HookResult { Ok(()) }
#[injectable(pre_destruct)]
async fn shutdown(&self) -> HookResult { Ok(()) }
}§On a trait (#[injectable(trait)])
Generates the infrastructure needed for Inject<dyn Trait> injection.
Use bind!(dyn Trait => Concrete) to wire a concrete implementation.
ⓘ
#[injectable(trait)]
pub trait EmailSender: Send + Sync {
async fn send(&self, to: &str, body: &str);
}
bind!(dyn EmailSender => SmtpSender);§On a function (#[injectable(factory)])
Transforms a function whose parameters carry #[injectable(inject)]
annotations into an async factory compatible with
#[injectable(inject(use_factory_async = path))].
ⓘ
#[injectable(factory)]
pub async fn make_client(
#[injectable(inject)] cfg: Arc<AppConfig>,
) -> Result<reqwest::Client, reqwest::Error> {
reqwest::Client::builder()
.timeout(Duration::from_secs(cfg.timeout_secs))
.build()
}
#[injectable]
pub struct WeatherService {
#[injectable(inject(use_factory_async = self::make_client))]
client: reqwest::Client,
}§Scope (on structs and impl blocks)
Type-safe idents (recommended):
scope = Singleton(default)scope = Transientscope = RequestScoped