use crate::lifetime::ServiceLifetime;
use std::any::Any;
use std::sync::Arc;
pub trait IServiceResolver: Send + Sync {
fn get_any(&self, key: &str) -> Option<Arc<dyn Any + Send + Sync>>;
fn get_keyed_any(&self, key: &str, variant: &str) -> Option<Arc<dyn Any + Send + Sync>>;
fn get<T: ?Sized + Sync + Send + 'static>(&self) -> Arc<T>
where
Self: Sized,
{
self.get_any(std::any::type_name::<T>())
.and_then(|a| a.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d)))
.unwrap_or_else(|| panic!("service not registered: {}", std::any::type_name::<T>()))
}
fn try_get<T: ?Sized + Sync + Send + 'static>(&self) -> Option<Arc<T>>
where
Self: Sized,
{
self.get_any(std::any::type_name::<T>())
.and_then(|a| a.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d)))
}
fn get_keyed<T: ?Sized + Sync + Send + 'static>(&self, variant: &str) -> Arc<T>
where
Self: Sized,
{
self.get_keyed_any(std::any::type_name::<T>(), variant)
.and_then(|a| a.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d)))
.unwrap_or_else(|| {
panic!(
"keyed service not registered: {}:{}",
std::any::type_name::<T>(),
variant
)
})
}
fn try_get_keyed<T: ?Sized + Sync + Send + 'static>(&self, variant: &str) -> Option<Arc<T>>
where
Self: Sized,
{
self.get_keyed_any(std::any::type_name::<T>(), variant)
.and_then(|a| a.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d)))
}
}
pub struct ServiceEntry {
pub cache_key: usize,
pub key: Option<String>,
pub type_name: &'static str, pub factory: ServiceFactory,
pub lifetime: ServiceLifetime,
}
pub type ServiceFactory =
Arc<dyn Fn(&dyn IServiceResolver) -> Arc<dyn Any + Send + Sync> + Send + Sync>;