use std::{any::Any, marker::PhantomData, sync::Arc};
use crate::{Container, DiError, ResolutionContext};
pub struct Provider<T> {
container: Container,
context: ResolutionContext,
_marker: PhantomData<fn() -> T>,
}
impl<T> Clone for Provider<T> {
fn clone(&self) -> Self {
Self {
container: self.container.clone(),
context: self.context.clone(),
_marker: PhantomData,
}
}
}
impl<T> Provider<T>
where
T: Any + Send + Sync,
{
#[doc(hidden)]
pub fn from_context(container: Container, context: ResolutionContext) -> Self {
Self {
container,
context,
_marker: PhantomData,
}
}
pub async fn get(&self) -> Result<Arc<T>, DiError> {
self.container.resolve_dependency::<T>(&self.context).await
}
}
pub struct Lazy<T> {
container: Container,
context: ResolutionContext,
cell: tokio::sync::OnceCell<Arc<T>>,
}
impl<T> Lazy<T>
where
T: Any + Send + Sync,
{
#[doc(hidden)]
pub fn from_context(container: Container, context: ResolutionContext) -> Self {
Self {
container,
context,
cell: tokio::sync::OnceCell::new(),
}
}
pub async fn get(&self) -> Result<&Arc<T>, DiError> {
self.cell
.get_or_try_init(|| async {
self.container.resolve_dependency::<T>(&self.context).await
})
.await
}
}