diff options
Diffstat (limited to 'src/di_container/blocking')
| -rw-r--r-- | src/di_container/blocking/binding/builder.rs | 69 | ||||
| -rw-r--r-- | src/di_container/blocking/binding/scope_configurator.rs | 69 | ||||
| -rw-r--r-- | src/di_container/blocking/binding/when_configurator.rs | 18 | ||||
| -rw-r--r-- | src/di_container/blocking/mod.rs | 146 | 
4 files changed, 154 insertions, 148 deletions
diff --git a/src/di_container/blocking/binding/builder.rs b/src/di_container/blocking/binding/builder.rs index e1c1561..7aa1755 100644 --- a/src/di_container/blocking/binding/builder.rs +++ b/src/di_container/blocking/binding/builder.rs @@ -5,6 +5,7 @@ use std::any::type_name;  use std::marker::PhantomData;  use std::rc::Rc; +use crate::dependency_history::IDependencyHistory;  use crate::di_container::blocking::binding::scope_configurator::BindingScopeConfigurator;  #[cfg(feature = "factory")]  use crate::di_container::blocking::binding::when_configurator::BindingWhenConfigurator; @@ -15,24 +16,33 @@ use crate::interfaces::injectable::Injectable;  /// Binding builder for type `Interface` inside a [`IDIContainer`].  ///  /// [`IDIContainer`]: crate::di_container::blocking::IDIContainer -pub struct BindingBuilder<Interface, DIContainerType> +pub struct BindingBuilder<Interface, DIContainerType, DependencyHistoryType>  where      Interface: 'static + ?Sized, -    DIContainerType: IDIContainer, +    DIContainerType: IDIContainer<DependencyHistoryType>, +    DependencyHistoryType: IDependencyHistory,  {      di_container: Rc<DIContainerType>, +    dependency_history_factory: fn() -> DependencyHistoryType, +      interface_phantom: PhantomData<Interface>,  } -impl<Interface, DIContainerType> BindingBuilder<Interface, DIContainerType> +impl<Interface, DIContainerType, DependencyHistoryType> +    BindingBuilder<Interface, DIContainerType, DependencyHistoryType>  where      Interface: 'static + ?Sized, -    DIContainerType: IDIContainer, +    DIContainerType: IDIContainer<DependencyHistoryType>, +    DependencyHistoryType: IDependencyHistory + 'static,  { -    pub(crate) fn new(di_container: Rc<DIContainerType>) -> Self +    pub(crate) fn new( +        di_container: Rc<DIContainerType>, +        dependency_history_factory: fn() -> DependencyHistoryType, +    ) -> Self      {          Self {              di_container, +            dependency_history_factory,              interface_phantom: PhantomData,          }      } @@ -82,11 +92,16 @@ where      pub fn to<Implementation>(          &self,      ) -> Result< -        BindingScopeConfigurator<Interface, Implementation, DIContainerType>, +        BindingScopeConfigurator< +            Interface, +            Implementation, +            DIContainerType, +            DependencyHistoryType, +        >,          BindingBuilderError,      >      where -        Implementation: Injectable<DIContainerType>, +        Implementation: Injectable<DIContainerType, DependencyHistoryType>,      {          {              if self.di_container.has_binding::<Interface>(None) { @@ -97,8 +112,10 @@ where              }          } -        let binding_scope_configurator = -            BindingScopeConfigurator::new(self.di_container.clone()); +        let binding_scope_configurator = BindingScopeConfigurator::new( +            self.di_container.clone(), +            self.dependency_history_factory, +        );          binding_scope_configurator.in_transient_scope(); @@ -176,7 +193,10 @@ where      pub fn to_factory<Args, Return, Func>(          &self,          factory_func: &'static Func, -    ) -> Result<BindingWhenConfigurator<Interface, DIContainerType>, BindingBuilderError> +    ) -> Result< +        BindingWhenConfigurator<Interface, DIContainerType, DependencyHistoryType>, +        BindingBuilderError, +    >      where          Args: 'static,          Return: 'static + ?Sized, @@ -262,7 +282,10 @@ where      pub fn to_default_factory<Return, FactoryFunc>(          &self,          factory_func: &'static FactoryFunc, -    ) -> Result<BindingWhenConfigurator<Interface, DIContainerType>, BindingBuilderError> +    ) -> Result< +        BindingWhenConfigurator<Interface, DIContainerType, DependencyHistoryType>, +        BindingBuilderError, +    >      where          Return: 'static + ?Sized,          FactoryFunc: Fn< @@ -323,8 +346,12 @@ mod tests          let binding_builder = BindingBuilder::<              dyn subjects::INumber, -            mocks::blocking_di_container::MockDIContainer, -        >::new(Rc::new(mock_di_container)); +            mocks::blocking_di_container::MockDIContainer<mocks::MockDependencyHistory>, +            mocks::MockDependencyHistory, +        >::new( +            Rc::new(mock_di_container), +            mocks::MockDependencyHistory::new, +        );          binding_builder.to::<subjects::Number>()?; @@ -358,8 +385,12 @@ mod tests          let binding_builder = BindingBuilder::<              IUserManagerFactory, -            mocks::blocking_di_container::MockDIContainer, -        >::new(Rc::new(mock_di_container)); +            mocks::blocking_di_container::MockDIContainer<mocks::MockDependencyHistory>, +            mocks::MockDependencyHistory, +        >::new( +            Rc::new(mock_di_container), +            mocks::MockDependencyHistory::new, +        );          binding_builder.to_factory(&|_| {              Box::new(move |_num, _text| { @@ -400,8 +431,12 @@ mod tests          let binding_builder = BindingBuilder::<              dyn subjects::IUserManager, -            mocks::blocking_di_container::MockDIContainer, -        >::new(Rc::new(mock_di_container)); +            mocks::blocking_di_container::MockDIContainer<mocks::MockDependencyHistory>, +            mocks::MockDependencyHistory, +        >::new( +            Rc::new(mock_di_container), +            mocks::MockDependencyHistory::new, +        );          binding_builder.to_default_factory(&|_| {              Box::new(move || { diff --git a/src/di_container/blocking/binding/scope_configurator.rs b/src/di_container/blocking/binding/scope_configurator.rs index dc33cbc..6c6c32d 100644 --- a/src/di_container/blocking/binding/scope_configurator.rs +++ b/src/di_container/blocking/binding/scope_configurator.rs @@ -4,6 +4,7 @@  use std::marker::PhantomData;  use std::rc::Rc; +use crate::dependency_history::IDependencyHistory;  use crate::di_container::blocking::binding::when_configurator::BindingWhenConfigurator;  use crate::di_container::blocking::IDIContainer;  use crate::errors::di_container::BindingScopeConfiguratorError; @@ -14,28 +15,45 @@ use crate::ptr::SingletonPtr;  /// Scope configurator for a binding for type 'Interface' inside a [`IDIContainer`].  ///  /// [`IDIContainer`]: crate::di_container::blocking::IDIContainer -pub struct BindingScopeConfigurator<Interface, Implementation, DIContainerType> -where +pub struct BindingScopeConfigurator< +    Interface, +    Implementation, +    DIContainerType, +    DependencyHistoryType, +> where      Interface: 'static + ?Sized, -    Implementation: Injectable<DIContainerType>, -    DIContainerType: IDIContainer, +    Implementation: Injectable<DIContainerType, DependencyHistoryType>, +    DIContainerType: IDIContainer<DependencyHistoryType>, +    DependencyHistoryType: IDependencyHistory,  {      di_container: Rc<DIContainerType>, +    dependency_history_factory: fn() -> DependencyHistoryType, +      interface_phantom: PhantomData<Interface>,      implementation_phantom: PhantomData<Implementation>,  } -impl<Interface, Implementation, DIContainerType> -    BindingScopeConfigurator<Interface, Implementation, DIContainerType> +impl<Interface, Implementation, DIContainerType, DependencyHistoryType> +    BindingScopeConfigurator< +        Interface, +        Implementation, +        DIContainerType, +        DependencyHistoryType, +    >  where      Interface: 'static + ?Sized, -    Implementation: Injectable<DIContainerType>, -    DIContainerType: IDIContainer, +    Implementation: Injectable<DIContainerType, DependencyHistoryType>, +    DIContainerType: IDIContainer<DependencyHistoryType>, +    DependencyHistoryType: IDependencyHistory + 'static,  { -    pub(crate) fn new(di_container: Rc<DIContainerType>) -> Self +    pub(crate) fn new( +        di_container: Rc<DIContainerType>, +        dependency_history_factory: fn() -> DependencyHistoryType, +    ) -> Self      {          Self {              di_container, +            dependency_history_factory,              interface_phantom: PhantomData,              implementation_phantom: PhantomData,          } @@ -47,11 +65,15 @@ where      #[allow(clippy::must_use_candidate)]      pub fn in_transient_scope(          &self, -    ) -> BindingWhenConfigurator<Interface, DIContainerType> +    ) -> BindingWhenConfigurator<Interface, DIContainerType, DependencyHistoryType>      {          self.di_container.set_binding::<Interface>(              None, -            Box::new(TransientTypeProvider::<Implementation, DIContainerType>::new()), +            Box::new(TransientTypeProvider::< +                Implementation, +                DIContainerType, +                DependencyHistoryType, +            >::new()),          );          BindingWhenConfigurator::new(self.di_container.clone()) @@ -64,13 +86,16 @@ where      pub fn in_singleton_scope(          &self,      ) -> Result< -        BindingWhenConfigurator<Interface, DIContainerType>, +        BindingWhenConfigurator<Interface, DIContainerType, DependencyHistoryType>,          BindingScopeConfiguratorError,      >      {          let singleton: SingletonPtr<Implementation> = SingletonPtr::from( -            Implementation::resolve(&self.di_container, Vec::new()) -                .map_err(BindingScopeConfiguratorError::SingletonResolveFailed)?, +            Implementation::resolve( +                &self.di_container, +                (self.dependency_history_factory)(), +            ) +            .map_err(BindingScopeConfiguratorError::SingletonResolveFailed)?,          );          self.di_container @@ -100,8 +125,12 @@ mod tests          let binding_scope_configurator = BindingScopeConfigurator::<              dyn subjects::IUserManager,              subjects::UserManager, -            mocks::blocking_di_container::MockDIContainer, -        >::new(Rc::new(di_container_mock)); +            mocks::blocking_di_container::MockDIContainer<mocks::MockDependencyHistory>, +            mocks::MockDependencyHistory, +        >::new( +            Rc::new(di_container_mock), +            mocks::MockDependencyHistory::new, +        );          binding_scope_configurator.in_transient_scope();      } @@ -120,8 +149,12 @@ mod tests          let binding_scope_configurator = BindingScopeConfigurator::<              dyn subjects::IUserManager,              subjects::UserManager, -            mocks::blocking_di_container::MockDIContainer, -        >::new(Rc::new(di_container_mock)); +            mocks::blocking_di_container::MockDIContainer<mocks::MockDependencyHistory>, +            mocks::MockDependencyHistory, +        >::new( +            Rc::new(di_container_mock), +            mocks::MockDependencyHistory::new, +        );          assert!(matches!(              binding_scope_configurator.in_singleton_scope(), diff --git a/src/di_container/blocking/binding/when_configurator.rs b/src/di_container/blocking/binding/when_configurator.rs index 49c9d9e..f93806b 100644 --- a/src/di_container/blocking/binding/when_configurator.rs +++ b/src/di_container/blocking/binding/when_configurator.rs @@ -5,31 +5,38 @@ use std::any::type_name;  use std::marker::PhantomData;  use std::rc::Rc; +use crate::dependency_history::IDependencyHistory;  use crate::di_container::blocking::IDIContainer;  use crate::errors::di_container::BindingWhenConfiguratorError;  /// When configurator for a binding for type 'Interface' inside a [`IDIContainer`].  ///  /// [`IDIContainer`]: crate::di_container::blocking::IDIContainer -pub struct BindingWhenConfigurator<Interface, DIContainerType> +pub struct BindingWhenConfigurator<Interface, DIContainerType, DependencyHistoryType>  where      Interface: 'static + ?Sized, -    DIContainerType: IDIContainer, +    DIContainerType: IDIContainer<DependencyHistoryType>, +    DependencyHistoryType: IDependencyHistory,  {      di_container: Rc<DIContainerType>, +      interface_phantom: PhantomData<Interface>, +    dependency_history_phantom: PhantomData<DependencyHistoryType>,  } -impl<Interface, DIContainerType> BindingWhenConfigurator<Interface, DIContainerType> +impl<Interface, DIContainerType, DependencyHistoryType> +    BindingWhenConfigurator<Interface, DIContainerType, DependencyHistoryType>  where      Interface: 'static + ?Sized, -    DIContainerType: IDIContainer, +    DIContainerType: IDIContainer<DependencyHistoryType>, +    DependencyHistoryType: IDependencyHistory,  {      pub(crate) fn new(di_container: Rc<DIContainerType>) -> Self      {          Self {              di_container,              interface_phantom: PhantomData, +            dependency_history_phantom: PhantomData,          }      } @@ -90,7 +97,8 @@ mod tests          let binding_when_configurator = BindingWhenConfigurator::<              dyn subjects::INumber, -            mocks::blocking_di_container::MockDIContainer, +            mocks::blocking_di_container::MockDIContainer<mocks::MockDependencyHistory>, +            mocks::MockDependencyHistory,          >::new(Rc::new(di_container_mock));          assert!(matches!( diff --git a/src/di_container/blocking/mod.rs b/src/di_container/blocking/mod.rs index bf77aba..6338118 100644 --- a/src/di_container/blocking/mod.rs +++ b/src/di_container/blocking/mod.rs @@ -54,6 +54,7 @@ use std::any::type_name;  use std::cell::RefCell;  use std::rc::Rc; +use crate::dependency_history::{DependencyHistory, IDependencyHistory};  use crate::di_container::binding_storage::DIContainerBindingStorage;  use crate::di_container::blocking::binding::builder::BindingBuilder;  use crate::errors::di_container::DIContainerError; @@ -65,10 +66,15 @@ pub mod binding;  pub mod prelude;  /// Blocking dependency injection container interface. -pub trait IDIContainer: Sized + 'static + details::DIContainerInternals +pub trait IDIContainer<DependencyHistoryType>: +    Sized + 'static + details::DIContainerInternals<DependencyHistoryType> +where +    DependencyHistoryType: IDependencyHistory,  {      /// Returns a new [`BindingBuilder`] for the given interface. -    fn bind<Interface>(self: &mut Rc<Self>) -> BindingBuilder<Interface, Self> +    fn bind<Interface>( +        self: &mut Rc<Self>, +    ) -> BindingBuilder<Interface, Self, DependencyHistoryType>      where          Interface: 'static + ?Sized; @@ -100,7 +106,7 @@ pub trait IDIContainer: Sized + 'static + details::DIContainerInternals      #[doc(hidden)]      fn get_bound<Interface>(          self: &Rc<Self>, -        dependency_history: Vec<&'static str>, +        dependency_history: DependencyHistoryType,          name: Option<&'static str>,      ) -> Result<SomePtr<Interface>, DIContainerError>      where @@ -110,7 +116,8 @@ pub trait IDIContainer: Sized + 'static + details::DIContainerInternals  /// Blocking dependency injection container.  pub struct DIContainer  { -    binding_storage: RefCell<DIContainerBindingStorage<dyn IProvider<Self>>>, +    binding_storage: +        RefCell<DIContainerBindingStorage<dyn IProvider<Self, DependencyHistory>>>,  }  impl DIContainer @@ -125,21 +132,23 @@ impl DIContainer      }  } -impl IDIContainer for DIContainer +impl IDIContainer<DependencyHistory> for DIContainer  {      #[must_use] -    fn bind<Interface>(self: &mut Rc<Self>) -> BindingBuilder<Interface, Self> +    fn bind<Interface>( +        self: &mut Rc<Self>, +    ) -> BindingBuilder<Interface, Self, DependencyHistory>      where          Interface: 'static + ?Sized,      { -        BindingBuilder::<Interface, Self>::new(self.clone()) +        BindingBuilder::new(self.clone(), DependencyHistory::new)      }      fn get<Interface>(self: &Rc<Self>) -> Result<SomePtr<Interface>, DIContainerError>      where          Interface: 'static + ?Sized,      { -        self.get_bound::<Interface>(Vec::new(), None) +        self.get_bound::<Interface>(DependencyHistory::new(), None)      }      fn get_named<Interface>( @@ -149,13 +158,13 @@ impl IDIContainer for DIContainer      where          Interface: 'static + ?Sized,      { -        self.get_bound::<Interface>(Vec::new(), Some(name)) +        self.get_bound::<Interface>(DependencyHistory::new(), Some(name))      }      #[doc(hidden)]      fn get_bound<Interface>(          self: &Rc<Self>, -        dependency_history: Vec<&'static str>, +        dependency_history: DependencyHistory,          name: Option<&'static str>,      ) -> Result<SomePtr<Interface>, DIContainerError>      where @@ -168,7 +177,7 @@ impl IDIContainer for DIContainer      }  } -impl details::DIContainerInternals for DIContainer +impl details::DIContainerInternals<DependencyHistory> for DIContainer  {      fn has_binding<Interface>(self: &Rc<Self>, name: Option<&'static str>) -> bool      where @@ -180,7 +189,7 @@ impl details::DIContainerInternals for DIContainer      fn set_binding<Interface>(          self: &Rc<Self>,          name: Option<&'static str>, -        provider: Box<dyn IProvider<Self>>, +        provider: Box<dyn IProvider<Self, DependencyHistory>>,      ) where          Interface: 'static + ?Sized,      { @@ -192,7 +201,7 @@ impl details::DIContainerInternals for DIContainer      fn remove_binding<Interface>(          self: &Rc<Self>,          name: Option<&'static str>, -    ) -> Option<Box<dyn IProvider<Self>>> +    ) -> Option<Box<dyn IProvider<Self, DependencyHistory>>>      where          Interface: 'static + ?Sized,      { @@ -204,7 +213,7 @@ impl DIContainer  {      fn handle_binding_providable<Interface>(          self: &Rc<Self>, -        binding_providable: Providable<Self>, +        binding_providable: Providable<Self, DependencyHistory>,      ) -> Result<SomePtr<Interface>, DIContainerError>      where          Interface: 'static + ?Sized, @@ -262,8 +271,8 @@ impl DIContainer      fn get_binding_providable<Interface>(          self: &Rc<Self>,          name: Option<&'static str>, -        dependency_history: Vec<&'static str>, -    ) -> Result<Providable<Self>, DIContainerError> +        dependency_history: DependencyHistory, +    ) -> Result<Providable<Self, DependencyHistory>, DIContainerError>      where          Interface: 'static + ?Sized,      { @@ -291,9 +300,12 @@ pub(crate) mod details  {      use std::rc::Rc; +    use crate::dependency_history::IDependencyHistory;      use crate::provider::blocking::IProvider; -    pub trait DIContainerInternals +    pub trait DIContainerInternals<DependencyHistoryType> +    where +        DependencyHistoryType: IDependencyHistory,      {          fn has_binding<Interface>(self: &Rc<Self>, name: Option<&'static str>) -> bool          where @@ -302,14 +314,14 @@ pub(crate) mod details          fn set_binding<Interface>(              self: &Rc<Self>,              name: Option<&'static str>, -            provider: Box<dyn IProvider<Self>>, +            provider: Box<dyn IProvider<Self, DependencyHistoryType>>,          ) where              Interface: 'static + ?Sized;          fn remove_binding<Interface>(              self: &Rc<Self>,              name: Option<&'static str>, -        ) -> Option<Box<dyn IProvider<Self>>> +        ) -> Option<Box<dyn IProvider<Self, DependencyHistoryType>>>          where              Interface: 'static + ?Sized;      } @@ -320,33 +332,16 @@ mod tests  {      use std::error::Error; -    use mockall::mock; -      use super::*; -    use crate::errors::injectable::InjectableError; -    use crate::provider::blocking::IProvider;      use crate::ptr::{SingletonPtr, TransientPtr}; -    use crate::test_utils::subjects; +    use crate::test_utils::{mocks, subjects};      #[test]      fn can_get() -> Result<(), Box<dyn Error>>      { -        mock! { -            Provider {} - -            impl IProvider<DIContainer> for Provider -            { -                fn provide( -                    &self, -                    di_container: &Rc<DIContainer>, -                    dependency_history: Vec<&'static str>, -                ) -> Result<Providable<DIContainer>, InjectableError>; -            } -        } -          let di_container = DIContainer::new(); -        let mut mock_provider = MockProvider::new(); +        let mut mock_provider = mocks::blocking_provider::MockProvider::new();          mock_provider.expect_provide().returning(|_, _| {              Ok(Providable::Transient(TransientPtr::new( @@ -369,22 +364,9 @@ mod tests      #[test]      fn can_get_named() -> Result<(), Box<dyn Error>>      { -        mock! { -            Provider {} - -            impl IProvider<DIContainer> for Provider -            { -                fn provide( -                    &self, -                    di_container: &Rc<DIContainer>, -                    dependency_history: Vec<&'static str>, -                ) -> Result<Providable<DIContainer>, InjectableError>; -            } -        } -          let di_container = DIContainer::new(); -        let mut mock_provider = MockProvider::new(); +        let mut mock_provider = mocks::blocking_provider::MockProvider::new();          mock_provider.expect_provide().returning(|_, _| {              Ok(Providable::Transient(TransientPtr::new( @@ -407,22 +389,9 @@ mod tests      #[test]      fn can_get_singleton() -> Result<(), Box<dyn Error>>      { -        mock! { -            Provider {} - -            impl IProvider<DIContainer> for Provider -            { -                fn provide( -                    &self, -                    di_container: &Rc<DIContainer>, -                    dependency_history: Vec<&'static str>, -                ) -> Result<Providable<DIContainer>, InjectableError>; -            } -        } -          let di_container = DIContainer::new(); -        let mut mock_provider = MockProvider::new(); +        let mut mock_provider = mocks::blocking_provider::MockProvider::new();          let mut singleton = SingletonPtr::new(subjects::Number::new()); @@ -452,22 +421,9 @@ mod tests      #[test]      fn can_get_singleton_named() -> Result<(), Box<dyn Error>>      { -        mock! { -            Provider {} - -            impl IProvider<DIContainer> for Provider -            { -                fn provide( -                    &self, -                    di_container: &Rc<DIContainer>, -                    dependency_history: Vec<&'static str>, -                ) -> Result<Providable<DIContainer>, InjectableError>; -            } -        } -          let di_container = DIContainer::new(); -        let mut mock_provider = MockProvider::new(); +        let mut mock_provider = mocks::blocking_provider::MockProvider::new();          let mut singleton = SingletonPtr::new(subjects::Number::new()); @@ -552,19 +508,6 @@ mod tests          #[crate::factory]          type IUserManagerFactory = dyn Fn(Vec<i128>) -> dyn IUserManager; -        mock! { -            Provider {} - -            impl IProvider<DIContainer> for Provider -            { -                fn provide( -                    &self, -                    di_container: &Rc<DIContainer>, -                    dependency_history: Vec<&'static str>, -                ) -> Result<Providable<DIContainer>, InjectableError>; -            } -        } -          let di_container = DIContainer::new();          let factory_func: &'static FactoryFunc = &|_: Rc<DIContainer>| { @@ -576,7 +519,7 @@ mod tests              })          }; -        let mut mock_provider = MockProvider::new(); +        let mut mock_provider = mocks::blocking_provider::MockProvider::new();          mock_provider.expect_provide().returning_st(|_, _| {              Ok(Providable::Factory(FactoryPtr::new(CastableFactory::new( @@ -649,19 +592,6 @@ mod tests          #[crate::factory]          type IUserManagerFactory = dyn Fn(Vec<i128>) -> dyn IUserManager; -        mock! { -            Provider {} - -            impl IProvider<DIContainer> for Provider -            { -                fn provide( -                    &self, -                    di_container: &Rc<DIContainer>, -                    dependency_history: Vec<&'static str>, -                ) -> Result<Providable<DIContainer>, InjectableError>; -            } -        } -          let di_container = DIContainer::new();          let factory_func: &'static FactoryFunc = &|_: Rc<DIContainer>| { @@ -673,7 +603,7 @@ mod tests              })          }; -        let mut mock_provider = MockProvider::new(); +        let mut mock_provider = mocks::blocking_provider::MockProvider::new();          mock_provider.expect_provide().returning_st(|_, _| {              Ok(Providable::Factory(FactoryPtr::new(CastableFactory::new(  | 
