1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
use crate::inject::Inject; use crate::provider::{Provider, RefProvider}; use crate::Container; #[macro_export] macro_rules! singleton { ($injectable:ty) => {{ struct SingletonProvider { instance: std::sync::Mutex<Option<std::sync::Arc<$injectable>>>, } impl $crate::Provider for SingletonProvider { type ProvidedType = std::sync::Arc<$injectable>; fn provide( &self, c: &$crate::Container, ) -> Result<Self::ProvidedType, $crate::InjectError> { loop { let mut instance = self.instance.lock().unwrap(); if let Some(instance) = instance.as_ref() { return Ok(std::sync::Arc::clone(&instance)); } else { let maybe_instance = $crate::get!(&c, $injectable); match maybe_instance { Ok(maybe_instance) => { *instance = Some(std::sync::Arc::new(maybe_instance)); } Err(err) => return Err(err), } } } } } SingletonProvider { instance: std::sync::Mutex::default(), } }}; }