diff options
Diffstat (limited to 'src/provider')
-rw-r--r-- | src/provider/async.rs | 103 | ||||
-rw-r--r-- | src/provider/blocking.rs | 75 |
2 files changed, 115 insertions, 63 deletions
diff --git a/src/provider/async.rs b/src/provider/async.rs index ec05b06..5b4bf89 100644 --- a/src/provider/async.rs +++ b/src/provider/async.rs @@ -3,16 +3,18 @@ use std::sync::Arc; use async_trait::async_trait; +use crate::di_container::asynchronous::IAsyncDIContainer; use crate::errors::injectable::InjectableError; use crate::interfaces::async_injectable::AsyncInjectable; use crate::ptr::{ThreadsafeSingletonPtr, TransientPtr}; -use crate::AsyncDIContainer; #[derive(strum_macros::Display, Debug)] -pub enum AsyncProvidable +pub enum AsyncProvidable<DIContainerType> +where + DIContainerType: IAsyncDIContainer, { - Transient(TransientPtr<dyn AsyncInjectable>), - Singleton(ThreadsafeSingletonPtr<dyn AsyncInjectable>), + Transient(TransientPtr<dyn AsyncInjectable<DIContainerType>>), + Singleton(ThreadsafeSingletonPtr<dyn AsyncInjectable<DIContainerType>>), #[cfg(feature = "factory")] Factory( crate::ptr::ThreadsafeFactoryPtr< @@ -34,18 +36,22 @@ pub enum AsyncProvidable } #[async_trait] -pub trait IAsyncProvider: Send + Sync +pub trait IAsyncProvider<DIContainerType>: Send + Sync +where + DIContainerType: IAsyncDIContainer, { async fn provide( &self, - di_container: &Arc<AsyncDIContainer>, + di_container: &Arc<DIContainerType>, dependency_history: Vec<&'static str>, - ) -> Result<AsyncProvidable, InjectableError>; + ) -> Result<AsyncProvidable<DIContainerType>, InjectableError>; - fn do_clone(&self) -> Box<dyn IAsyncProvider>; + fn do_clone(&self) -> Box<dyn IAsyncProvider<DIContainerType>>; } -impl Clone for Box<dyn IAsyncProvider> +impl<DIContainerType> Clone for Box<dyn IAsyncProvider<DIContainerType>> +where + DIContainerType: IAsyncDIContainer, { fn clone(&self) -> Self { @@ -53,104 +59,127 @@ impl Clone for Box<dyn IAsyncProvider> } } -pub struct AsyncTransientTypeProvider<InjectableType> +pub struct AsyncTransientTypeProvider<InjectableType, DIContainerType> where - InjectableType: AsyncInjectable, + InjectableType: AsyncInjectable<DIContainerType>, + DIContainerType: IAsyncDIContainer, { injectable_phantom: PhantomData<InjectableType>, + di_container_phantom: PhantomData<DIContainerType>, } -impl<InjectableType> AsyncTransientTypeProvider<InjectableType> +impl<InjectableType, DIContainerType> + AsyncTransientTypeProvider<InjectableType, DIContainerType> where - InjectableType: AsyncInjectable, + InjectableType: AsyncInjectable<DIContainerType>, + DIContainerType: IAsyncDIContainer, { pub fn new() -> Self { Self { injectable_phantom: PhantomData, + di_container_phantom: PhantomData, } } } #[async_trait] -impl<InjectableType> IAsyncProvider for AsyncTransientTypeProvider<InjectableType> +impl<InjectableType, DIContainerType> IAsyncProvider<DIContainerType> + for AsyncTransientTypeProvider<InjectableType, DIContainerType> where - InjectableType: AsyncInjectable, + InjectableType: AsyncInjectable<DIContainerType>, + DIContainerType: IAsyncDIContainer, { async fn provide( &self, - di_container: &Arc<AsyncDIContainer>, + di_container: &Arc<DIContainerType>, dependency_history: Vec<&'static str>, - ) -> Result<AsyncProvidable, InjectableError> + ) -> Result<AsyncProvidable<DIContainerType>, InjectableError> { Ok(AsyncProvidable::Transient( InjectableType::resolve(di_container, dependency_history).await?, )) } - fn do_clone(&self) -> Box<dyn IAsyncProvider> + fn do_clone(&self) -> Box<dyn IAsyncProvider<DIContainerType>> { Box::new(self.clone()) } } -impl<InjectableType> Clone for AsyncTransientTypeProvider<InjectableType> +impl<InjectableType, DIContainerType> Clone + for AsyncTransientTypeProvider<InjectableType, DIContainerType> where - InjectableType: AsyncInjectable, + InjectableType: AsyncInjectable<DIContainerType>, + DIContainerType: IAsyncDIContainer, { fn clone(&self) -> Self { Self { injectable_phantom: self.injectable_phantom, + di_container_phantom: self.di_container_phantom, } } } -pub struct AsyncSingletonProvider<InjectableType> +pub struct AsyncSingletonProvider<InjectableType, DIContainerType> where - InjectableType: AsyncInjectable, + InjectableType: AsyncInjectable<DIContainerType>, + DIContainerType: IAsyncDIContainer, { singleton: ThreadsafeSingletonPtr<InjectableType>, + + di_container_phantom: PhantomData<DIContainerType>, } -impl<InjectableType> AsyncSingletonProvider<InjectableType> +impl<InjectableType, DIContainerType> + AsyncSingletonProvider<InjectableType, DIContainerType> where - InjectableType: AsyncInjectable, + InjectableType: AsyncInjectable<DIContainerType>, + DIContainerType: IAsyncDIContainer, { pub fn new(singleton: ThreadsafeSingletonPtr<InjectableType>) -> Self { - Self { singleton } + Self { + singleton, + di_container_phantom: PhantomData, + } } } #[async_trait] -impl<InjectableType> IAsyncProvider for AsyncSingletonProvider<InjectableType> +impl<InjectableType, DIContainerType> IAsyncProvider<DIContainerType> + for AsyncSingletonProvider<InjectableType, DIContainerType> where - InjectableType: AsyncInjectable, + InjectableType: AsyncInjectable<DIContainerType>, + DIContainerType: IAsyncDIContainer, { async fn provide( &self, - _di_container: &Arc<AsyncDIContainer>, + _di_container: &Arc<DIContainerType>, _dependency_history: Vec<&'static str>, - ) -> Result<AsyncProvidable, InjectableError> + ) -> Result<AsyncProvidable<DIContainerType>, InjectableError> { Ok(AsyncProvidable::Singleton(self.singleton.clone())) } - fn do_clone(&self) -> Box<dyn IAsyncProvider> + fn do_clone(&self) -> Box<dyn IAsyncProvider<DIContainerType>> { Box::new(self.clone()) } } -impl<InjectableType> Clone for AsyncSingletonProvider<InjectableType> +impl<InjectableType, DIContainerType> Clone + for AsyncSingletonProvider<InjectableType, DIContainerType> where - InjectableType: AsyncInjectable, + InjectableType: AsyncInjectable<DIContainerType>, + DIContainerType: IAsyncDIContainer, { fn clone(&self) -> Self { Self { singleton: self.singleton.clone(), + di_container_phantom: PhantomData, } } } @@ -188,13 +217,15 @@ impl AsyncFactoryProvider #[cfg(feature = "factory")] #[async_trait] -impl IAsyncProvider for AsyncFactoryProvider +impl<DIContainerType> IAsyncProvider<DIContainerType> for AsyncFactoryProvider +where + DIContainerType: IAsyncDIContainer, { async fn provide( &self, - _di_container: &Arc<AsyncDIContainer>, + _di_container: &Arc<DIContainerType>, _dependency_history: Vec<&'static str>, - ) -> Result<AsyncProvidable, InjectableError> + ) -> Result<AsyncProvidable<DIContainerType>, InjectableError> { Ok(match self.variant { AsyncFactoryVariant::Normal => AsyncProvidable::Factory(self.factory.clone()), @@ -207,7 +238,7 @@ impl IAsyncProvider for AsyncFactoryProvider }) } - fn do_clone(&self) -> Box<dyn IAsyncProvider> + fn do_clone(&self) -> Box<dyn IAsyncProvider<DIContainerType>> { Box::new(self.clone()) } diff --git a/src/provider/blocking.rs b/src/provider/blocking.rs index 16e8847..b768b55 100644 --- a/src/provider/blocking.rs +++ b/src/provider/blocking.rs @@ -1,16 +1,18 @@ use std::marker::PhantomData; use std::rc::Rc; +use crate::di_container::blocking::IDIContainer; use crate::errors::injectable::InjectableError; use crate::interfaces::injectable::Injectable; use crate::ptr::{SingletonPtr, TransientPtr}; -use crate::DIContainer; #[derive(strum_macros::Display, Debug)] -pub enum Providable +pub enum Providable<DIContainerType> +where + DIContainerType: IDIContainer, { - Transient(TransientPtr<dyn Injectable>), - Singleton(SingletonPtr<dyn Injectable>), + Transient(TransientPtr<dyn Injectable<DIContainerType>>), + Singleton(SingletonPtr<dyn Injectable<DIContainerType>>), #[cfg(feature = "factory")] Factory(crate::ptr::FactoryPtr<dyn crate::interfaces::any_factory::AnyFactory>), #[cfg(feature = "factory")] @@ -19,43 +21,52 @@ pub enum Providable ), } -pub trait IProvider +pub trait IProvider<DIContainerType> +where + DIContainerType: IDIContainer, { fn provide( &self, - di_container: &Rc<DIContainer>, + di_container: &Rc<DIContainerType>, dependency_history: Vec<&'static str>, - ) -> Result<Providable, InjectableError>; + ) -> Result<Providable<DIContainerType>, InjectableError>; } -pub struct TransientTypeProvider<InjectableType> +pub struct TransientTypeProvider<InjectableType, DIContainerType> where - InjectableType: Injectable, + InjectableType: Injectable<DIContainerType>, + DIContainerType: IDIContainer, { injectable_phantom: PhantomData<InjectableType>, + di_container_phantom: PhantomData<DIContainerType>, } -impl<InjectableType> TransientTypeProvider<InjectableType> +impl<InjectableType, DIContainerType> + TransientTypeProvider<InjectableType, DIContainerType> where - InjectableType: Injectable, + InjectableType: Injectable<DIContainerType>, + DIContainerType: IDIContainer, { pub fn new() -> Self { Self { injectable_phantom: PhantomData, + di_container_phantom: PhantomData, } } } -impl<InjectableType> IProvider for TransientTypeProvider<InjectableType> +impl<InjectableType, DIContainerType> IProvider<DIContainerType> + for TransientTypeProvider<InjectableType, DIContainerType> where - InjectableType: Injectable, + InjectableType: Injectable<DIContainerType>, + DIContainerType: IDIContainer, { fn provide( &self, - di_container: &Rc<DIContainer>, + di_container: &Rc<DIContainerType>, dependency_history: Vec<&'static str>, - ) -> Result<Providable, InjectableError> + ) -> Result<Providable<DIContainerType>, InjectableError> { Ok(Providable::Transient(InjectableType::resolve( di_container, @@ -64,32 +75,40 @@ where } } -pub struct SingletonProvider<InjectableType> +pub struct SingletonProvider<InjectableType, DIContainerType> where - InjectableType: Injectable, + InjectableType: Injectable<DIContainerType>, + DIContainerType: IDIContainer, { singleton: SingletonPtr<InjectableType>, + di_container_phantom: PhantomData<DIContainerType>, } -impl<InjectableType> SingletonProvider<InjectableType> +impl<InjectableType, DIContainerType> SingletonProvider<InjectableType, DIContainerType> where - InjectableType: Injectable, + InjectableType: Injectable<DIContainerType>, + DIContainerType: IDIContainer, { pub fn new(singleton: SingletonPtr<InjectableType>) -> Self { - Self { singleton } + Self { + singleton, + di_container_phantom: PhantomData, + } } } -impl<InjectableType> IProvider for SingletonProvider<InjectableType> +impl<InjectableType, DIContainerType> IProvider<DIContainerType> + for SingletonProvider<InjectableType, DIContainerType> where - InjectableType: Injectable, + InjectableType: Injectable<DIContainerType>, + DIContainerType: IDIContainer, { fn provide( &self, - _di_container: &Rc<DIContainer>, + _di_container: &Rc<DIContainerType>, _dependency_history: Vec<&'static str>, - ) -> Result<Providable, InjectableError> + ) -> Result<Providable<DIContainerType>, InjectableError> { Ok(Providable::Singleton(self.singleton.clone())) } @@ -118,13 +137,15 @@ impl FactoryProvider } #[cfg(feature = "factory")] -impl IProvider for FactoryProvider +impl<DIContainerType> IProvider<DIContainerType> for FactoryProvider +where + DIContainerType: IDIContainer, { fn provide( &self, - _di_container: &Rc<DIContainer>, + _di_container: &Rc<DIContainerType>, _dependency_history: Vec<&'static str>, - ) -> Result<Providable, InjectableError> + ) -> Result<Providable<DIContainerType>, InjectableError> { Ok(if self.is_default_factory { Providable::DefaultFactory(self.factory.clone()) |