From aa548ded39c7ba1927019c748c359523b21d59e8 Mon Sep 17 00:00:00 2001 From: HampusM Date: Sat, 29 Oct 2022 14:38:51 +0200 Subject: refactor!: add dependency history type BREAKING CHANGE: Binding builders & configurators now take dependency history type arguments, the DetectedCircular variant of InjectableError now contains a dependency history field & the injectable traits take dependency history instead of a Vec --- src/provider/blocking.rs | 124 +++++++++++++++++++++++++++++------------------ 1 file changed, 77 insertions(+), 47 deletions(-) (limited to 'src/provider/blocking.rs') diff --git a/src/provider/blocking.rs b/src/provider/blocking.rs index e1e2aad..ebe0c37 100644 --- a/src/provider/blocking.rs +++ b/src/provider/blocking.rs @@ -1,18 +1,20 @@ use std::marker::PhantomData; use std::rc::Rc; +use crate::dependency_history::IDependencyHistory; use crate::di_container::blocking::IDIContainer; use crate::errors::injectable::InjectableError; use crate::interfaces::injectable::Injectable; use crate::ptr::{SingletonPtr, TransientPtr}; #[derive(strum_macros::Display, Debug)] -pub enum Providable +pub enum Providable where - DIContainerType: IDIContainer, + DIContainerType: IDIContainer, + DependencyHistoryType: IDependencyHistory, { - Transient(TransientPtr>), - Singleton(SingletonPtr>), + Transient(TransientPtr>), + Singleton(SingletonPtr>), #[cfg(feature = "factory")] Factory(crate::ptr::FactoryPtr), #[cfg(feature = "factory")] @@ -22,52 +24,59 @@ where } #[cfg_attr(test, mockall::automock, allow(dead_code))] -pub trait IProvider +pub trait IProvider where - DIContainerType: IDIContainer, + DIContainerType: IDIContainer, + DependencyHistoryType: IDependencyHistory, { fn provide( &self, di_container: &Rc, - dependency_history: Vec<&'static str>, - ) -> Result, InjectableError>; + dependency_history: DependencyHistoryType, + ) -> Result, InjectableError>; } -pub struct TransientTypeProvider +pub struct TransientTypeProvider where - InjectableType: Injectable, - DIContainerType: IDIContainer, + InjectableType: Injectable, + DIContainerType: IDIContainer, + DependencyHistoryType: IDependencyHistory, { injectable_phantom: PhantomData, di_container_phantom: PhantomData, + dependency_history_phantom: PhantomData, } -impl - TransientTypeProvider +impl + TransientTypeProvider where - InjectableType: Injectable, - DIContainerType: IDIContainer, + InjectableType: Injectable, + DIContainerType: IDIContainer, + DependencyHistoryType: IDependencyHistory, { pub fn new() -> Self { Self { injectable_phantom: PhantomData, di_container_phantom: PhantomData, + dependency_history_phantom: PhantomData, } } } -impl IProvider - for TransientTypeProvider +impl + IProvider + for TransientTypeProvider where - InjectableType: Injectable, - DIContainerType: IDIContainer, + InjectableType: Injectable, + DIContainerType: IDIContainer, + DependencyHistoryType: IDependencyHistory, { fn provide( &self, di_container: &Rc, - dependency_history: Vec<&'static str>, - ) -> Result, InjectableError> + dependency_history: DependencyHistoryType, + ) -> Result, InjectableError> { Ok(Providable::Transient(InjectableType::resolve( di_container, @@ -76,40 +85,48 @@ where } } -pub struct SingletonProvider +pub struct SingletonProvider where - InjectableType: Injectable, - DIContainerType: IDIContainer, + InjectableType: Injectable, + DIContainerType: IDIContainer, + DependencyHistoryType: IDependencyHistory, { singleton: SingletonPtr, + di_container_phantom: PhantomData, + dependency_history_phantom: PhantomData, } -impl SingletonProvider +impl + SingletonProvider where - InjectableType: Injectable, - DIContainerType: IDIContainer, + InjectableType: Injectable, + DIContainerType: IDIContainer, + DependencyHistoryType: IDependencyHistory, { pub fn new(singleton: SingletonPtr) -> Self { Self { singleton, di_container_phantom: PhantomData, + dependency_history_phantom: PhantomData, } } } -impl IProvider - for SingletonProvider +impl + IProvider + for SingletonProvider where - InjectableType: Injectable, - DIContainerType: IDIContainer, + InjectableType: Injectable, + DIContainerType: IDIContainer, + DependencyHistoryType: IDependencyHistory, { fn provide( &self, _di_container: &Rc, - _dependency_history: Vec<&'static str>, - ) -> Result, InjectableError> + _dependency_history: DependencyHistoryType, + ) -> Result, InjectableError> { Ok(Providable::Singleton(self.singleton.clone())) } @@ -138,15 +155,17 @@ impl FactoryProvider } #[cfg(feature = "factory")] -impl IProvider for FactoryProvider +impl + IProvider for FactoryProvider where - DIContainerType: IDIContainer, + DIContainerType: IDIContainer, + DependencyHistoryType: IDependencyHistory, { fn provide( &self, _di_container: &Rc, - _dependency_history: Vec<&'static str>, - ) -> Result, InjectableError> + _dependency_history: DependencyHistoryType, + ) -> Result, InjectableError> { Ok(if self.is_default_factory { Providable::DefaultFactory(self.factory.clone()) @@ -169,14 +188,18 @@ mod tests { let transient_type_provider = TransientTypeProvider::< subjects::UserManager, - mocks::blocking_di_container::MockDIContainer, + mocks::blocking_di_container::MockDIContainer, + mocks::MockDependencyHistory, >::new(); let di_container = mocks::blocking_di_container::MockDIContainer::new(); + let dependency_history_mock = mocks::MockDependencyHistory::new(); + assert!( matches!( - transient_type_provider.provide(&Rc::new(di_container), vec![])?, + transient_type_provider + .provide(&Rc::new(di_container), dependency_history_mock)?, Providable::Transient(_) ), "The provided type is not transient" @@ -188,17 +211,22 @@ mod tests #[test] fn singleton_provider_works() -> Result<(), Box> { - let singleton_provider = - SingletonProvider::< - subjects::UserManager, - mocks::blocking_di_container::MockDIContainer, - >::new(SingletonPtr::new(subjects::UserManager {})); + let singleton_provider = SingletonProvider::< + subjects::UserManager, + mocks::blocking_di_container::MockDIContainer, + mocks::MockDependencyHistory, + >::new(SingletonPtr::new( + subjects::UserManager {}, + )); let di_container = mocks::blocking_di_container::MockDIContainer::new(); assert!( matches!( - singleton_provider.provide(&Rc::new(di_container), vec![])?, + singleton_provider.provide( + &Rc::new(di_container), + mocks::MockDependencyHistory::new() + )?, Providable::Singleton(_) ), "The provided type is not a singleton" @@ -227,7 +255,8 @@ mod tests assert!( matches!( - factory_provider.provide(&di_container, vec![])?, + factory_provider + .provide(&di_container, mocks::MockDependencyHistory::new())?, Providable::Factory(_) ), "The provided type is not a factory" @@ -235,7 +264,8 @@ mod tests assert!( matches!( - default_factory_provider.provide(&di_container, vec![])?, + default_factory_provider + .provide(&di_container, mocks::MockDependencyHistory::new())?, Providable::DefaultFactory(_) ), "The provided type is not a default factory" -- cgit v1.2.3-18-g5258