diff options
Diffstat (limited to 'src/di_container/asynchronous/binding')
3 files changed, 195 insertions, 264 deletions
diff --git a/src/di_container/asynchronous/binding/builder.rs b/src/di_container/asynchronous/binding/builder.rs index 6daba30..d9ad0e6 100644 --- a/src/di_container/asynchronous/binding/builder.rs +++ b/src/di_container/asynchronous/binding/builder.rs @@ -1,4 +1,6 @@ -//! Binding builder for types inside of a [`AsyncDIContainer`]. +//! Binding builder for types inside of a [`IAsyncDIContainer`]. +//! +//! [`IAsyncDIContainer`]: crate::di_container::asynchronous::IAsyncDIContainer  use std::any::type_name;  use std::marker::PhantomData;  use std::sync::Arc; @@ -6,29 +8,33 @@ use std::sync::Arc;  use crate::di_container::asynchronous::binding::scope_configurator::AsyncBindingScopeConfigurator;  #[cfg(feature = "factory")]  use crate::di_container::asynchronous::binding::when_configurator::AsyncBindingWhenConfigurator; +use crate::di_container::asynchronous::IAsyncDIContainer;  use crate::errors::async_di_container::AsyncBindingBuilderError;  use crate::interfaces::async_injectable::AsyncInjectable; -use crate::AsyncDIContainer;  /// Alias for a threadsafe boxed function.  #[cfg(feature = "factory")]  #[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))]  pub type BoxFn<Args, Return> = Box<(dyn Fn<Args, Output = Return> + Send + Sync)>; -/// Binding builder for type `Interface` inside a [`AsyncDIContainer`]. -pub struct AsyncBindingBuilder<Interface> +/// Binding builder for type `Interface` inside a [`IAsyncDIContainer`]. +/// +/// [`IAsyncDIContainer`]: crate::di_container::asynchronous::IAsyncDIContainer +pub struct AsyncBindingBuilder<Interface, DIContainerType>  where      Interface: 'static + ?Sized + Send + Sync, +    DIContainerType: IAsyncDIContainer,  { -    di_container: Arc<AsyncDIContainer>, +    di_container: Arc<DIContainerType>,      interface_phantom: PhantomData<Interface>,  } -impl<Interface> AsyncBindingBuilder<Interface> +impl<Interface, DIContainerType> AsyncBindingBuilder<Interface, DIContainerType>  where      Interface: 'static + ?Sized + Send + Sync, +    DIContainerType: IAsyncDIContainer,  { -    pub(crate) fn new(di_container: Arc<AsyncDIContainer>) -> Self +    pub(crate) fn new(di_container: Arc<DIContainerType>) -> Self      {          Self {              di_container, @@ -37,20 +43,21 @@ where      }      /// Creates a binding of type `Interface` to type `Implementation` inside of the -    /// associated [`AsyncDIContainer`]. +    /// associated [`IAsyncDIContainer`].      ///      /// The scope of the binding is transient. But that can be changed by using the      /// returned [`AsyncBindingScopeConfigurator`]      ///      /// # Errors -    /// Will return Err if the associated [`AsyncDIContainer`] already have a binding for +    /// Will return Err if the associated [`IAsyncDIContainer`] already have a binding for      /// the interface.      ///      /// # Examples      /// ```      /// # use std::error::Error;      /// # -    /// # use syrette::{AsyncDIContainer, injectable}; +    /// # use syrette::injectable; +    /// # use syrette::di_container::asynchronous::prelude::*;      /// #      /// # trait Foo: Send + Sync {}      /// # @@ -76,24 +83,22 @@ where      /// # Ok(())      /// # }      /// ``` +    /// +    /// [`IAsyncDIContainer`]: crate::di_container::asynchronous::IAsyncDIContainer      pub async fn to<Implementation>(          &self,      ) -> Result< -        AsyncBindingScopeConfigurator<Interface, Implementation>, +        AsyncBindingScopeConfigurator<Interface, Implementation, DIContainerType>,          AsyncBindingBuilderError,      >      where -        Implementation: AsyncInjectable, +        Implementation: AsyncInjectable<DIContainerType>,      { -        { -            let bindings_lock = self.di_container.bindings.lock().await; - -            if bindings_lock.has::<Interface>(None) { -                return Err(AsyncBindingBuilderError::BindingAlreadyExists(type_name::< -                    Interface, -                >( -                ))); -            } +        if self.di_container.has_binding::<Interface>(None).await { +            return Err(AsyncBindingBuilderError::BindingAlreadyExists(type_name::< +                Interface, +            >( +            )));          }          let binding_scope_configurator = @@ -105,17 +110,18 @@ where      }      /// Creates a binding of factory type `Interface` to a factory inside of the -    /// associated [`AsyncDIContainer`]. +    /// associated [`IAsyncDIContainer`].      ///      /// # Errors -    /// Will return Err if the associated [`AsyncDIContainer`] already have a binding +    /// Will return Err if the associated [`IAsyncDIContainer`] already have a binding      /// for the interface.      ///      /// # Examples      /// ```      /// # use std::error::Error;      /// # -    /// # use syrette::{AsyncDIContainer, factory}; +    /// # use syrette::{factory}; +    /// # use syrette::di_container::asynchronous::prelude::*;      /// # use syrette::ptr::TransientPtr;      /// #      /// # trait Foo: Send + Sync {} @@ -150,25 +156,28 @@ where      /// # Ok(())      /// # }      /// ``` +    /// +    /// [`IAsyncDIContainer`]: crate::di_container::asynchronous::IAsyncDIContainer      #[cfg(feature = "factory")]      #[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))]      pub async fn to_factory<Args, Return, FactoryFunc>(          &self,          factory_func: &'static FactoryFunc, -    ) -> Result<AsyncBindingWhenConfigurator<Interface>, AsyncBindingBuilderError> +    ) -> Result< +        AsyncBindingWhenConfigurator<Interface, DIContainerType>, +        AsyncBindingBuilderError, +    >      where          Args: 'static,          Return: 'static + ?Sized,          Interface: Fn<Args, Output = Return> + Send + Sync,          FactoryFunc: -            Fn<(Arc<AsyncDIContainer>,), Output = BoxFn<Args, Return>> + Send + Sync, +            Fn<(Arc<DIContainerType>,), Output = BoxFn<Args, Return>> + Send + Sync,      {          use crate::castable_factory::threadsafe::ThreadsafeCastableFactory;          use crate::provider::r#async::AsyncFactoryVariant; -        let mut bindings_lock = self.di_container.bindings.lock().await; - -        if bindings_lock.has::<Interface>(None) { +        if self.di_container.has_binding::<Interface>(None).await {              return Err(AsyncBindingBuilderError::BindingAlreadyExists(type_name::<                  Interface,              >( @@ -177,22 +186,24 @@ where          let factory_impl = ThreadsafeCastableFactory::new(factory_func); -        bindings_lock.set::<Interface>( -            None, -            Box::new(crate::provider::r#async::AsyncFactoryProvider::new( -                crate::ptr::ThreadsafeFactoryPtr::new(factory_impl), -                AsyncFactoryVariant::Normal, -            )), -        ); +        self.di_container +            .set_binding::<Interface>( +                None, +                Box::new(crate::provider::r#async::AsyncFactoryProvider::new( +                    crate::ptr::ThreadsafeFactoryPtr::new(factory_impl), +                    AsyncFactoryVariant::Normal, +                )), +            ) +            .await;          Ok(AsyncBindingWhenConfigurator::new(self.di_container.clone()))      }      /// Creates a binding of factory type `Interface` to a async factory inside of the -    /// associated [`AsyncDIContainer`]. +    /// associated [`IAsyncDIContainer`].      ///      /// # Errors -    /// Will return Err if the associated [`AsyncDIContainer`] already have a binding +    /// Will return Err if the associated [`IAsyncDIContainer`] already have a binding      /// for the interface.      ///      /// # Examples @@ -200,7 +211,8 @@ where      /// # use std::error::Error;      /// # use std::time::Duration;      /// # -    /// # use syrette::{AsyncDIContainer, factory, async_closure}; +    /// # use syrette::{factory, async_closure}; +    /// # use syrette::di_container::asynchronous::prelude::*;      /// # use syrette::ptr::TransientPtr;      /// #      /// # trait Foo: Send + Sync {} @@ -237,19 +249,24 @@ where      /// # Ok(())      /// # }      /// ``` +    /// +    /// [`IAsyncDIContainer`]: crate::di_container::asynchronous::IAsyncDIContainer      #[cfg(feature = "factory")]      #[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))]      pub async fn to_async_factory<Args, Return, FactoryFunc>(          &self,          factory_func: &'static FactoryFunc, -    ) -> Result<AsyncBindingWhenConfigurator<Interface>, AsyncBindingBuilderError> +    ) -> Result< +        AsyncBindingWhenConfigurator<Interface, DIContainerType>, +        AsyncBindingBuilderError, +    >      where          Args: 'static,          Return: 'static + ?Sized,          Interface:              Fn<Args, Output = crate::future::BoxFuture<'static, Return>> + Send + Sync,          FactoryFunc: Fn< -                (Arc<AsyncDIContainer>,), +                (Arc<DIContainerType>,),                  Output = BoxFn<Args, crate::future::BoxFuture<'static, Return>>,              > + Send              + Sync, @@ -257,9 +274,7 @@ where          use crate::castable_factory::threadsafe::ThreadsafeCastableFactory;          use crate::provider::r#async::AsyncFactoryVariant; -        let mut bindings_lock = self.di_container.bindings.lock().await; - -        if bindings_lock.has::<Interface>(None) { +        if self.di_container.has_binding::<Interface>(None).await {              return Err(AsyncBindingBuilderError::BindingAlreadyExists(type_name::<                  Interface,              >( @@ -268,29 +283,31 @@ where          let factory_impl = ThreadsafeCastableFactory::new(factory_func); -        bindings_lock.set::<Interface>( -            None, -            Box::new(crate::provider::r#async::AsyncFactoryProvider::new( -                crate::ptr::ThreadsafeFactoryPtr::new(factory_impl), -                AsyncFactoryVariant::Normal, -            )), -        ); +        self.di_container +            .set_binding::<Interface>( +                None, +                Box::new(crate::provider::r#async::AsyncFactoryProvider::new( +                    crate::ptr::ThreadsafeFactoryPtr::new(factory_impl), +                    AsyncFactoryVariant::Normal, +                )), +            ) +            .await;          Ok(AsyncBindingWhenConfigurator::new(self.di_container.clone()))      }      /// Creates a binding of type `Interface` to a factory that takes no arguments -    /// inside of the associated [`AsyncDIContainer`]. +    /// inside of the associated [`IAsyncDIContainer`].      ///      /// # Errors -    /// Will return Err if the associated [`AsyncDIContainer`] already have a binding +    /// Will return Err if the associated [`IAsyncDIContainer`] already have a binding      /// for the interface.      ///      /// # Examples      /// ```      /// # use std::error::Error;      /// # -    /// # use syrette::AsyncDIContainer; +    /// # use syrette::di_container::asynchronous::prelude::*;      /// # use syrette::ptr::TransientPtr;      /// #      /// # trait Foo: Send + Sync {} @@ -325,16 +342,21 @@ where      /// # Ok(())      /// # }      /// ``` +    /// +    /// [`IAsyncDIContainer`]: crate::di_container::asynchronous::IAsyncDIContainer      #[cfg(feature = "factory")]      #[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))]      pub async fn to_default_factory<Return, FactoryFunc>(          &self,          factory_func: &'static FactoryFunc, -    ) -> Result<AsyncBindingWhenConfigurator<Interface>, AsyncBindingBuilderError> +    ) -> Result< +        AsyncBindingWhenConfigurator<Interface, DIContainerType>, +        AsyncBindingBuilderError, +    >      where          Return: 'static + ?Sized,          FactoryFunc: Fn< -                (Arc<AsyncDIContainer>,), +                (Arc<DIContainerType>,),                  Output = BoxFn<(), crate::ptr::TransientPtr<Return>>,              > + Send              + Sync, @@ -342,9 +364,7 @@ where          use crate::castable_factory::threadsafe::ThreadsafeCastableFactory;          use crate::provider::r#async::AsyncFactoryVariant; -        let mut bindings_lock = self.di_container.bindings.lock().await; - -        if bindings_lock.has::<Interface>(None) { +        if self.di_container.has_binding::<Interface>(None).await {              return Err(AsyncBindingBuilderError::BindingAlreadyExists(type_name::<                  Interface,              >( @@ -353,22 +373,24 @@ where          let factory_impl = ThreadsafeCastableFactory::new(factory_func); -        bindings_lock.set::<Interface>( -            None, -            Box::new(crate::provider::r#async::AsyncFactoryProvider::new( -                crate::ptr::ThreadsafeFactoryPtr::new(factory_impl), -                AsyncFactoryVariant::Default, -            )), -        ); +        self.di_container +            .set_binding::<Interface>( +                None, +                Box::new(crate::provider::r#async::AsyncFactoryProvider::new( +                    crate::ptr::ThreadsafeFactoryPtr::new(factory_impl), +                    AsyncFactoryVariant::Default, +                )), +            ) +            .await;          Ok(AsyncBindingWhenConfigurator::new(self.di_container.clone()))      }      /// Creates a binding of factory type `Interface` to a async factory inside of the -    /// associated [`AsyncDIContainer`]. +    /// associated [`IAsyncDIContainer`].      ///      /// # Errors -    /// Will return Err if the associated [`AsyncDIContainer`] already have a binding +    /// Will return Err if the associated [`IAsyncDIContainer`] already have a binding      /// for the interface.      ///      /// # Examples @@ -376,7 +398,8 @@ where      /// # use std::error::Error;      /// # use std::time::Duration;      /// # -    /// # use syrette::{AsyncDIContainer, async_closure}; +    /// # use syrette::async_closure; +    /// # use syrette::di_container::asynchronous::prelude::*;      /// # use syrette::ptr::TransientPtr;      /// #      /// # trait Foo: Send + Sync {} @@ -413,16 +436,21 @@ where      /// # Ok(())      /// # }      /// ``` +    /// +    /// [`IAsyncDIContainer`]: crate::di_container::asynchronous::IAsyncDIContainer      #[cfg(feature = "factory")]      #[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))]      pub async fn to_async_default_factory<Return, FactoryFunc>(          &self,          factory_func: &'static FactoryFunc, -    ) -> Result<AsyncBindingWhenConfigurator<Interface>, AsyncBindingBuilderError> +    ) -> Result< +        AsyncBindingWhenConfigurator<Interface, DIContainerType>, +        AsyncBindingBuilderError, +    >      where          Return: 'static + ?Sized,          FactoryFunc: Fn< -                (Arc<AsyncDIContainer>,), +                (Arc<DIContainerType>,),                  Output = BoxFn<(), crate::future::BoxFuture<'static, Return>>,              > + Send              + Sync, @@ -430,9 +458,7 @@ where          use crate::castable_factory::threadsafe::ThreadsafeCastableFactory;          use crate::provider::r#async::AsyncFactoryVariant; -        let mut bindings_lock = self.di_container.bindings.lock().await; - -        if bindings_lock.has::<Interface>(None) { +        if self.di_container.has_binding::<Interface>(None).await {              return Err(AsyncBindingBuilderError::BindingAlreadyExists(type_name::<                  Interface,              >( @@ -441,13 +467,15 @@ where          let factory_impl = ThreadsafeCastableFactory::new(factory_func); -        bindings_lock.set::<Interface>( -            None, -            Box::new(crate::provider::r#async::AsyncFactoryProvider::new( -                crate::ptr::ThreadsafeFactoryPtr::new(factory_impl), -                AsyncFactoryVariant::AsyncDefault, -            )), -        ); +        self.di_container +            .set_binding::<Interface>( +                None, +                Box::new(crate::provider::r#async::AsyncFactoryProvider::new( +                    crate::ptr::ThreadsafeFactoryPtr::new(factory_impl), +                    AsyncFactoryVariant::AsyncDefault, +                )), +            ) +            .await;          Ok(AsyncBindingWhenConfigurator::new(self.di_container.clone()))      } @@ -458,127 +486,40 @@ mod tests  {      use std::error::Error; +    use mockall::predicate::eq; +      use super::*; -    use crate::ptr::TransientPtr; +    use crate::test_utils::mocks::async_di_container::MockAsyncDIContainer;      use crate::test_utils::subjects_async;      #[tokio::test]      async fn can_bind_to() -> Result<(), Box<dyn Error>>      { -        let mut di_container = AsyncDIContainer::new(); +        let mut di_container_mock = MockAsyncDIContainer::new(); -        { -            assert_eq!(di_container.bindings.lock().await.count(), 0); -        } +        di_container_mock +            .expect_has_binding::<dyn subjects_async::IUserManager>() +            .with(eq(None)) +            .return_once(|_name| false) +            .once(); -        di_container -            .bind::<dyn subjects_async::IUserManager>() -            .to::<subjects_async::UserManager>() -            .await?; +        di_container_mock +            .expect_set_binding::<dyn subjects_async::IUserManager>() +            .withf(|name, _provider| name.is_none()) +            .return_once(|_name, _provider| ()) +            .once(); -        { -            assert_eq!(di_container.bindings.lock().await.count(), 1); -        } - -        Ok(()) -    } - -    #[tokio::test] -    async fn can_bind_to_transient() -> Result<(), Box<dyn Error>> -    { -        let mut di_container = AsyncDIContainer::new(); - -        { -            assert_eq!(di_container.bindings.lock().await.count(), 0); -        } +        let binding_builder = AsyncBindingBuilder::< +            dyn subjects_async::IUserManager, +            MockAsyncDIContainer, +        >::new(Arc::new(di_container_mock)); -        di_container -            .bind::<dyn subjects_async::IUserManager>() -            .to::<subjects_async::UserManager>() -            .await? -            .in_transient_scope() -            .await; - -        { -            assert_eq!(di_container.bindings.lock().await.count(), 1); -        } - -        Ok(()) -    } - -    #[tokio::test] -    async fn can_bind_to_transient_when_named() -> Result<(), Box<dyn Error>> -    { -        let mut di_container = AsyncDIContainer::new(); - -        { -            assert_eq!(di_container.bindings.lock().await.count(), 0); -        } - -        di_container -            .bind::<dyn subjects_async::IUserManager>() -            .to::<subjects_async::UserManager>() -            .await? -            .in_transient_scope() -            .await -            .when_named("regular") -            .await?; - -        { -            assert_eq!(di_container.bindings.lock().await.count(), 1); -        } - -        Ok(()) -    } - -    #[tokio::test] -    async fn can_bind_to_singleton() -> Result<(), Box<dyn Error>> -    { -        let mut di_container = AsyncDIContainer::new(); - -        { -            assert_eq!(di_container.bindings.lock().await.count(), 0); -        } - -        di_container -            .bind::<dyn subjects_async::IUserManager>() -            .to::<subjects_async::UserManager>() -            .await? -            .in_singleton_scope() -            .await?; - -        { -            assert_eq!(di_container.bindings.lock().await.count(), 1); -        } - -        Ok(()) -    } - -    #[tokio::test] -    async fn can_bind_to_singleton_when_named() -> Result<(), Box<dyn Error>> -    { -        let mut di_container = AsyncDIContainer::new(); - -        { -            assert_eq!(di_container.bindings.lock().await.count(), 0); -        } - -        di_container -            .bind::<dyn subjects_async::IUserManager>() -            .to::<subjects_async::UserManager>() -            .await? -            .in_singleton_scope() -            .await? -            .when_named("cool") -            .await?; - -        { -            assert_eq!(di_container.bindings.lock().await.count(), 1); -        } +        binding_builder.to::<subjects_async::UserManager>().await?;          Ok(())      } +    /*      #[tokio::test]      #[cfg(feature = "factory")]      async fn can_bind_to_factory() -> Result<(), Box<dyn Error>> @@ -613,41 +554,5 @@ mod tests          Ok(())      } - -    #[tokio::test] -    #[cfg(feature = "factory")] -    async fn can_bind_to_factory_when_named() -> Result<(), Box<dyn Error>> -    { -        use crate as syrette; -        use crate::factory; - -        #[factory(threadsafe = true)] -        type IUserManagerFactory = dyn Fn() -> dyn subjects_async::IUserManager; - -        let mut di_container = AsyncDIContainer::new(); - -        { -            assert_eq!(di_container.bindings.lock().await.count(), 0); -        } - -        di_container -            .bind::<IUserManagerFactory>() -            .to_factory(&|_| { -                Box::new(|| { -                    let user_manager: TransientPtr<dyn subjects_async::IUserManager> = -                        TransientPtr::new(subjects_async::UserManager::new()); - -                    user_manager -                }) -            }) -            .await? -            .when_named("awesome") -            .await?; - -        { -            assert_eq!(di_container.bindings.lock().await.count(), 1); -        } - -        Ok(()) -    } +    */  } diff --git a/src/di_container/asynchronous/binding/scope_configurator.rs b/src/di_container/asynchronous/binding/scope_configurator.rs index 2b0f0b3..fd42fea 100644 --- a/src/di_container/asynchronous/binding/scope_configurator.rs +++ b/src/di_container/asynchronous/binding/scope_configurator.rs @@ -1,31 +1,38 @@ -//! Scope configurator for a binding for types inside of a [`AsyncDIContainer`]. +//! Scope configurator for a binding for types inside of a [`IAsyncDIContainer`]. +//! +//! [`IAsyncDIContainer`]: crate::di_container::asynchronous::IAsyncDIContainer  use std::marker::PhantomData;  use std::sync::Arc;  use crate::di_container::asynchronous::binding::when_configurator::AsyncBindingWhenConfigurator; +use crate::di_container::asynchronous::IAsyncDIContainer;  use crate::errors::async_di_container::AsyncBindingScopeConfiguratorError;  use crate::interfaces::async_injectable::AsyncInjectable;  use crate::provider::r#async::{AsyncSingletonProvider, AsyncTransientTypeProvider};  use crate::ptr::ThreadsafeSingletonPtr; -use crate::AsyncDIContainer; -/// Scope configurator for a binding for type 'Interface' inside a [`AsyncDIContainer`]. -pub struct AsyncBindingScopeConfigurator<Interface, Implementation> +/// Scope configurator for a binding for type 'Interface' inside a [`IAsyncDIContainer`]. +/// +/// [`IAsyncDIContainer`]: crate::di_container::asynchronous::IAsyncDIContainer +pub struct AsyncBindingScopeConfigurator<Interface, Implementation, DIContainerType>  where      Interface: 'static + ?Sized + Send + Sync, -    Implementation: AsyncInjectable, +    Implementation: AsyncInjectable<DIContainerType>, +    DIContainerType: IAsyncDIContainer,  { -    di_container: Arc<AsyncDIContainer>, +    di_container: Arc<DIContainerType>,      interface_phantom: PhantomData<Interface>,      implementation_phantom: PhantomData<Implementation>,  } -impl<Interface, Implementation> AsyncBindingScopeConfigurator<Interface, Implementation> +impl<Interface, Implementation, DIContainerType> +    AsyncBindingScopeConfigurator<Interface, Implementation, DIContainerType>  where      Interface: 'static + ?Sized + Send + Sync, -    Implementation: AsyncInjectable, +    Implementation: AsyncInjectable<DIContainerType>, +    DIContainerType: IAsyncDIContainer,  { -    pub(crate) fn new(di_container: Arc<AsyncDIContainer>) -> Self +    pub(crate) fn new(di_container: Arc<DIContainerType>) -> Self      {          Self {              di_container, @@ -37,14 +44,18 @@ where      /// Configures the binding to be in a transient scope.      ///      /// This is the default. -    pub async fn in_transient_scope(&self) -> AsyncBindingWhenConfigurator<Interface> +    pub async fn in_transient_scope( +        &self, +    ) -> AsyncBindingWhenConfigurator<Interface, DIContainerType>      { -        let mut bindings_lock = self.di_container.bindings.lock().await; - -        bindings_lock.set::<Interface>( -            None, -            Box::new(AsyncTransientTypeProvider::<Implementation>::new()), -        ); +        self.di_container +            .set_binding::<Interface>( +                None, +                Box::new( +                    AsyncTransientTypeProvider::<Implementation, DIContainerType>::new(), +                ), +            ) +            .await;          AsyncBindingWhenConfigurator::new(self.di_container.clone())      } @@ -55,7 +66,10 @@ where      /// Will return Err if resolving the implementation fails.      pub async fn in_singleton_scope(          &self, -    ) -> Result<AsyncBindingWhenConfigurator<Interface>, AsyncBindingScopeConfiguratorError> +    ) -> Result< +        AsyncBindingWhenConfigurator<Interface, DIContainerType>, +        AsyncBindingScopeConfiguratorError, +    >      {          let singleton: ThreadsafeSingletonPtr<Implementation> =              ThreadsafeSingletonPtr::from( @@ -66,10 +80,12 @@ where                      )?,              ); -        let mut bindings_lock = self.di_container.bindings.lock().await; - -        bindings_lock -            .set::<Interface>(None, Box::new(AsyncSingletonProvider::new(singleton))); +        self.di_container +            .set_binding::<Interface>( +                None, +                Box::new(AsyncSingletonProvider::new(singleton)), +            ) +            .await;          Ok(AsyncBindingWhenConfigurator::new(self.di_container.clone()))      } diff --git a/src/di_container/asynchronous/binding/when_configurator.rs b/src/di_container/asynchronous/binding/when_configurator.rs index b245ad8..3175420 100644 --- a/src/di_container/asynchronous/binding/when_configurator.rs +++ b/src/di_container/asynchronous/binding/when_configurator.rs @@ -1,25 +1,31 @@ -//! When configurator for a binding for types inside of a [`AsyncDIContainer`]. +//! When configurator for a binding for types inside of a [`IAsyncDIContainer`]. +//! +//! [`IAsyncDIContainer`]: crate::di_container::asynchronous::IAsyncDIContainer  use std::any::type_name;  use std::marker::PhantomData;  use std::sync::Arc; +use crate::di_container::asynchronous::IAsyncDIContainer;  use crate::errors::async_di_container::AsyncBindingWhenConfiguratorError; -use crate::AsyncDIContainer; -/// When configurator for a binding for type 'Interface' inside a [`AsyncDIContainer`]. -pub struct AsyncBindingWhenConfigurator<Interface> +/// When configurator for a binding for type 'Interface' inside a [`IAsyncDIContainer`]. +/// +/// [`IAsyncDIContainer`]: crate::di_container::asynchronous::IAsyncDIContainer +pub struct AsyncBindingWhenConfigurator<Interface, DIContainerType>  where      Interface: 'static + ?Sized + Send + Sync, +    DIContainerType: IAsyncDIContainer,  { -    di_container: Arc<AsyncDIContainer>, +    di_container: Arc<DIContainerType>,      interface_phantom: PhantomData<Interface>,  } -impl<Interface> AsyncBindingWhenConfigurator<Interface> +impl<Interface, DIContainerType> AsyncBindingWhenConfigurator<Interface, DIContainerType>  where      Interface: 'static + ?Sized + Send + Sync, +    DIContainerType: IAsyncDIContainer,  { -    pub(crate) fn new(di_container: Arc<AsyncDIContainer>) -> Self +    pub(crate) fn new(di_container: Arc<DIContainerType>) -> Self      {          Self {              di_container, @@ -36,18 +42,22 @@ where          name: &'static str,      ) -> Result<(), AsyncBindingWhenConfiguratorError>      { -        let mut bindings_lock = self.di_container.bindings.lock().await; +        let binding = self +            .di_container +            .remove_binding::<Interface>(None) +            .await +            .map_or_else( +                || { +                    Err(AsyncBindingWhenConfiguratorError::BindingNotFound( +                        type_name::<Interface>(), +                    )) +                }, +                Ok, +            )?; -        let binding = bindings_lock.remove::<Interface>(None).map_or_else( -            || { -                Err(AsyncBindingWhenConfiguratorError::BindingNotFound( -                    type_name::<Interface>(), -                )) -            }, -            Ok, -        )?; - -        bindings_lock.set::<Interface>(Some(name), binding); +        self.di_container +            .set_binding::<Interface>(Some(name), binding) +            .await;          Ok(())      }  | 
