diff options
Diffstat (limited to 'src/di_container')
| -rw-r--r-- | src/di_container/asynchronous/binding/builder.rs | 74 | ||||
| -rw-r--r-- | src/di_container/asynchronous/binding/scope_configurator.rs | 29 | ||||
| -rw-r--r-- | src/di_container/asynchronous/binding/when_configurator.rs | 11 | ||||
| -rw-r--r-- | src/di_container/asynchronous/mod.rs | 84 | 
4 files changed, 92 insertions, 106 deletions
| diff --git a/src/di_container/asynchronous/binding/builder.rs b/src/di_container/asynchronous/binding/builder.rs index c253929..acb1c69 100644 --- a/src/di_container/asynchronous/binding/builder.rs +++ b/src/di_container/asynchronous/binding/builder.rs @@ -1,7 +1,6 @@  //! Binding builder for types inside of a [`AsyncDIContainer`].  use std::any::type_name;  use std::marker::PhantomData; -use std::sync::Arc;  use crate::di_container::asynchronous::binding::scope_configurator::AsyncBindingScopeConfigurator;  #[cfg(feature = "factory")] @@ -21,22 +20,22 @@ pub type BoxFn<Args, Return> = Box<(dyn Fn<Args, Output = Return> + Send + Sync)  /// Binding builder for type `Interface` inside a [`AsyncDIContainer`].  #[must_use = "No binding will be created if you don't use the binding builder"] -pub struct AsyncBindingBuilder<Interface> +pub struct AsyncBindingBuilder<'di_container, Interface>  where      Interface: 'static + ?Sized + Send + Sync,  { -    di_container: Arc<AsyncDIContainer>, +    di_container: &'di_container AsyncDIContainer,      dependency_history_factory: fn() -> DependencyHistory,      interface_phantom: PhantomData<Interface>,  } -impl<Interface> AsyncBindingBuilder<Interface> +impl<'di_container, Interface> AsyncBindingBuilder<'di_container, Interface>  where      Interface: 'static + ?Sized + Send + Sync,  {      pub(crate) fn new( -        di_container: Arc<AsyncDIContainer>, +        di_container: &'di_container AsyncDIContainer,          dependency_history_factory: fn() -> DependencyHistory,      ) -> Self      { @@ -91,7 +90,7 @@ where      pub async fn to<Implementation>(          self,      ) -> Result< -        AsyncBindingScopeConfigurator<Interface, Implementation>, +        AsyncBindingScopeConfigurator<'di_container, Interface, Implementation>,          AsyncBindingBuilderError,      >      where @@ -109,7 +108,7 @@ where          }          let binding_scope_configurator = AsyncBindingScopeConfigurator::new( -            self.di_container.clone(), +            self.di_container,              self.dependency_history_factory,          ); @@ -170,13 +169,15 @@ where      pub async fn to_factory<Args, Return, FactoryFunc>(          self,          factory_func: &'static FactoryFunc, -    ) -> Result<AsyncBindingWhenConfigurator<Interface>, AsyncBindingBuilderError> +    ) -> Result< +        AsyncBindingWhenConfigurator<'di_container, Interface>, +        AsyncBindingBuilderError, +    >      where          Args: std::marker::Tuple + 'static,          Return: 'static + ?Sized,          Interface: Fn<Args, Output = Return> + Send + Sync, -        FactoryFunc: -            Fn<(Arc<AsyncDIContainer>,), Output = BoxFn<Args, Return>> + Send + Sync, +        FactoryFunc: Fn(&AsyncDIContainer) -> BoxFn<Args, Return> + Send + Sync,      {          use crate::private::castable_factory::threadsafe::ThreadsafeCastableFactory;          use crate::provider::r#async::AsyncFactoryVariant; @@ -204,7 +205,7 @@ where              )              .await; -        Ok(AsyncBindingWhenConfigurator::new(self.di_container.clone())) +        Ok(AsyncBindingWhenConfigurator::new(self.di_container))      }      /// Creates a binding of factory type `Interface` to a async factory inside of the @@ -268,16 +269,19 @@ where      pub async fn to_async_factory<Args, Return, FactoryFunc>(          self,          factory_func: &'static FactoryFunc, -    ) -> Result<AsyncBindingWhenConfigurator<Interface>, AsyncBindingBuilderError> +    ) -> Result< +        AsyncBindingWhenConfigurator<'di_container, Interface>, +        AsyncBindingBuilderError, +    >      where          Args: std::marker::Tuple + 'static,          Return: 'static + ?Sized,          Interface:              Fn<Args, Output = crate::future::BoxFuture<'static, Return>> + Send + Sync, -        FactoryFunc: Fn< -                (Arc<AsyncDIContainer>,), -                Output = BoxFn<Args, crate::future::BoxFuture<'static, Return>>, -            > + Send +        FactoryFunc: Fn( +                &AsyncDIContainer, +            ) -> BoxFn<Args, crate::future::BoxFuture<'static, Return>> +            + Send              + Sync,      {          use crate::private::castable_factory::threadsafe::ThreadsafeCastableFactory; @@ -306,7 +310,7 @@ where              )              .await; -        Ok(AsyncBindingWhenConfigurator::new(self.di_container.clone())) +        Ok(AsyncBindingWhenConfigurator::new(self.di_container))      }      /// Creates a binding of type `Interface` to a factory that takes no arguments @@ -360,13 +364,14 @@ where      pub async fn to_default_factory<Return, FactoryFunc>(          self,          factory_func: &'static FactoryFunc, -    ) -> Result<AsyncBindingWhenConfigurator<Interface>, AsyncBindingBuilderError> +    ) -> Result< +        AsyncBindingWhenConfigurator<'di_container, Interface>, +        AsyncBindingBuilderError, +    >      where          Return: 'static + ?Sized, -        FactoryFunc: Fn< -                (Arc<AsyncDIContainer>,), -                Output = BoxFn<(), crate::ptr::TransientPtr<Return>>, -            > + Send +        FactoryFunc: Fn(&AsyncDIContainer) -> BoxFn<(), crate::ptr::TransientPtr<Return>> +            + Send              + Sync,      {          use crate::private::castable_factory::threadsafe::ThreadsafeCastableFactory; @@ -395,7 +400,7 @@ where              )              .await; -        Ok(AsyncBindingWhenConfigurator::new(self.di_container.clone())) +        Ok(AsyncBindingWhenConfigurator::new(self.di_container))      }      /// Creates a binding of factory type `Interface` to a async factory inside of the @@ -454,13 +459,14 @@ where      pub async fn to_async_default_factory<Return, FactoryFunc>(          self,          factory_func: &'static FactoryFunc, -    ) -> Result<AsyncBindingWhenConfigurator<Interface>, AsyncBindingBuilderError> +    ) -> Result< +        AsyncBindingWhenConfigurator<'di_container, Interface>, +        AsyncBindingBuilderError, +    >      where          Return: 'static + ?Sized, -        FactoryFunc: Fn< -                (Arc<AsyncDIContainer>,), -                Output = BoxFn<(), crate::future::BoxFuture<'static, Return>>, -            > + Send +        FactoryFunc: Fn(&AsyncDIContainer) -> BoxFn<(), crate::future::BoxFuture<'static, Return>> +            + Send              + Sync,      {          use crate::private::castable_factory::threadsafe::ThreadsafeCastableFactory; @@ -489,7 +495,7 @@ where              )              .await; -        Ok(AsyncBindingWhenConfigurator::new(self.di_container.clone())) +        Ok(AsyncBindingWhenConfigurator::new(self.di_container))      }  } @@ -524,7 +530,7 @@ mod tests          let binding_builder =              AsyncBindingBuilder::<dyn subjects_async::IUserManager>::new( -                Arc::new(di_container_mock), +                &di_container_mock,                  MockDependencyHistory::new,              ); @@ -565,7 +571,7 @@ mod tests              .once();          let binding_builder = AsyncBindingBuilder::<IUserManagerFactory>::new( -            Arc::new(di_container_mock), +            &di_container_mock,              MockDependencyHistory::new,          ); @@ -614,7 +620,7 @@ mod tests              .once();          let binding_builder = AsyncBindingBuilder::<IUserManagerFactory>::new( -            Arc::new(di_container_mock), +            &di_container_mock,              MockDependencyHistory::new,          ); @@ -659,7 +665,7 @@ mod tests          let binding_builder =              AsyncBindingBuilder::<dyn subjects_async::IUserManager>::new( -                Arc::new(di_container_mock), +                &di_container_mock,                  MockDependencyHistory::new,              ); @@ -705,7 +711,7 @@ mod tests          let binding_builder =              AsyncBindingBuilder::<dyn subjects_async::IUserManager>::new( -                Arc::new(di_container_mock), +                &di_container_mock,                  MockDependencyHistory::new,              ); diff --git a/src/di_container/asynchronous/binding/scope_configurator.rs b/src/di_container/asynchronous/binding/scope_configurator.rs index 3557202..f079234 100644 --- a/src/di_container/asynchronous/binding/scope_configurator.rs +++ b/src/di_container/asynchronous/binding/scope_configurator.rs @@ -1,6 +1,5 @@  //! Scope configurator for a binding for types inside of a [`AsyncDIContainer`].  use std::marker::PhantomData; -use std::sync::Arc;  use crate::di_container::asynchronous::binding::when_configurator::AsyncBindingWhenConfigurator;  use crate::di_container::BindingOptions; @@ -14,25 +13,26 @@ use_double!(crate::dependency_history::DependencyHistory);  use_double!(crate::di_container::asynchronous::AsyncDIContainer);  /// Scope configurator for a binding for type `Interface` inside a [`AsyncDIContainer`]. -pub struct AsyncBindingScopeConfigurator<Interface, Implementation> +pub struct AsyncBindingScopeConfigurator<'di_container, Interface, Implementation>  where      Interface: 'static + ?Sized + Send + Sync,      Implementation: AsyncInjectable<AsyncDIContainer>,  { -    di_container: Arc<AsyncDIContainer>, +    di_container: &'di_container AsyncDIContainer,      dependency_history_factory: fn() -> DependencyHistory,      interface_phantom: PhantomData<Interface>,      implementation_phantom: PhantomData<Implementation>,  } -impl<Interface, Implementation> AsyncBindingScopeConfigurator<Interface, Implementation> +impl<'di_container, Interface, Implementation> +    AsyncBindingScopeConfigurator<'di_container, Interface, Implementation>  where      Interface: 'static + ?Sized + Send + Sync,      Implementation: AsyncInjectable<AsyncDIContainer>,  {      pub(crate) fn new( -        di_container: Arc<AsyncDIContainer>, +        di_container: &'di_container AsyncDIContainer,          dependency_history_factory: fn() -> DependencyHistory,      ) -> Self      { @@ -47,11 +47,13 @@ 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<'di_container, Interface>      {          self.set_in_transient_scope().await; -        AsyncBindingWhenConfigurator::new(self.di_container.clone()) +        AsyncBindingWhenConfigurator::new(self.di_container)      }      /// Configures the binding to be in a singleton scope. @@ -60,12 +62,15 @@ where      /// Will return Err if resolving the implementation fails.      pub async fn in_singleton_scope(          self, -    ) -> Result<AsyncBindingWhenConfigurator<Interface>, AsyncBindingScopeConfiguratorError> +    ) -> Result< +        AsyncBindingWhenConfigurator<'di_container, Interface>, +        AsyncBindingScopeConfiguratorError, +    >      {          let singleton: ThreadsafeSingletonPtr<Implementation> =              ThreadsafeSingletonPtr::from(                  Implementation::resolve( -                    &self.di_container, +                    self.di_container,                      (self.dependency_history_factory)(),                  )                  .await @@ -79,7 +84,7 @@ where              )              .await; -        Ok(AsyncBindingWhenConfigurator::new(self.di_container.clone())) +        Ok(AsyncBindingWhenConfigurator::new(self.di_container))      }      pub(crate) async fn set_in_transient_scope(&self) @@ -118,7 +123,7 @@ mod tests              AsyncBindingScopeConfigurator::<                  dyn subjects_async::IUserManager,                  subjects_async::UserManager, -            >::new(Arc::new(di_container_mock), MockDependencyHistory::new); +            >::new(&di_container_mock, MockDependencyHistory::new);          binding_scope_configurator.in_transient_scope().await;      } @@ -138,7 +143,7 @@ mod tests              AsyncBindingScopeConfigurator::<                  dyn subjects_async::IUserManager,                  subjects_async::UserManager, -            >::new(Arc::new(di_container_mock), MockDependencyHistory::new); +            >::new(&di_container_mock, MockDependencyHistory::new);          assert!(binding_scope_configurator              .in_singleton_scope() diff --git a/src/di_container/asynchronous/binding/when_configurator.rs b/src/di_container/asynchronous/binding/when_configurator.rs index 3c1de7c..b7c2767 100644 --- a/src/di_container/asynchronous/binding/when_configurator.rs +++ b/src/di_container/asynchronous/binding/when_configurator.rs @@ -1,7 +1,6 @@  //! When configurator for a binding for types inside of a [`AsyncDIContainer`].  use std::any::type_name;  use std::marker::PhantomData; -use std::sync::Arc;  use crate::di_container::BindingOptions;  use crate::errors::async_di_container::AsyncBindingWhenConfiguratorError; @@ -10,20 +9,20 @@ use crate::util::use_double;  use_double!(crate::di_container::asynchronous::AsyncDIContainer);  /// When configurator for a binding for type `Interface` inside a [`AsyncDIContainer`]. -pub struct AsyncBindingWhenConfigurator<Interface> +pub struct AsyncBindingWhenConfigurator<'di_container, Interface>  where      Interface: 'static + ?Sized + Send + Sync,  { -    di_container: Arc<AsyncDIContainer>, +    di_container: &'di_container AsyncDIContainer,      interface_phantom: PhantomData<Interface>,  } -impl<Interface> AsyncBindingWhenConfigurator<Interface> +impl<'di_container, Interface> AsyncBindingWhenConfigurator<'di_container, Interface>  where      Interface: 'static + ?Sized + Send + Sync,  { -    pub(crate) fn new(di_container: Arc<AsyncDIContainer>) -> Self +    pub(crate) fn new(di_container: &'di_container AsyncDIContainer) -> Self      {          Self {              di_container, @@ -90,7 +89,7 @@ mod tests          let binding_when_configurator = AsyncBindingWhenConfigurator::<              dyn subjects_async::INumber, -        >::new(Arc::new(di_container_mock)); +        >::new(&di_container_mock);          assert!(binding_when_configurator              .when_named("awesome") diff --git a/src/di_container/asynchronous/mod.rs b/src/di_container/asynchronous/mod.rs index 827364d..4be232d 100644 --- a/src/di_container/asynchronous/mod.rs +++ b/src/di_container/asynchronous/mod.rs @@ -71,6 +71,7 @@ use_double!(crate::dependency_history::DependencyHistory);  pub mod binding;  /// Async dependency injection container. +#[derive(Default)]  pub struct AsyncDIContainer  {      binding_storage: Mutex<DIContainerBindingStorage<dyn IAsyncProvider<Self>>>, @@ -80,11 +81,11 @@ impl AsyncDIContainer  {      /// Returns a new `AsyncDIContainer`.      #[must_use] -    pub fn new() -> Arc<Self> +    pub fn new() -> Self      { -        Arc::new(Self { +        Self {              binding_storage: Mutex::new(DIContainerBindingStorage::new()), -        }) +        }      }  } @@ -93,7 +94,7 @@ impl AsyncDIContainer  {      /// Returns a new [`AsyncBindingBuilder`] for the given interface.      #[allow(clippy::missing_panics_doc)] -    pub fn bind<Interface>(self: &mut Arc<Self>) -> AsyncBindingBuilder<Interface> +    pub fn bind<Interface>(&mut self) -> AsyncBindingBuilder<'_, Interface>      where          Interface: 'static + ?Sized + Send + Sync,      { @@ -101,7 +102,7 @@ impl AsyncDIContainer          panic!("Bind function is unusable when testing");          #[cfg(not(test))] -        AsyncBindingBuilder::new(self.clone(), DependencyHistory::new) +        AsyncBindingBuilder::new(self, DependencyHistory::new)      }      /// Returns the type bound with `Interface`. @@ -112,7 +113,7 @@ impl AsyncDIContainer      /// - Resolving the binding for `Interface` fails      /// - Casting the binding for `Interface` fails      pub async fn get<Interface>( -        self: &Arc<Self>, +        &self,      ) -> Result<SomePtr<Interface>, AsyncDIContainerError>      where          Interface: 'static + ?Sized + Send + Sync, @@ -129,7 +130,7 @@ impl AsyncDIContainer      /// - Resolving the binding for `Interface` fails      /// - Casting the binding for `Interface` fails      pub async fn get_named<Interface>( -        self: &Arc<Self>, +        &self,          name: &'static str,      ) -> Result<SomePtr<Interface>, AsyncDIContainerError>      where @@ -177,7 +178,7 @@ impl AsyncDIContainer      /// # });      /// ```      pub async fn get_bound<Interface>( -        self: &Arc<Self>, +        &self,          dependency_history: DependencyHistory,          binding_options: BindingOptions<'static>,      ) -> Result<SomePtr<Interface>, AsyncDIContainerError> @@ -192,7 +193,7 @@ impl AsyncDIContainer      }      async fn has_binding<Interface>( -        self: &Arc<Self>, +        &self,          binding_options: BindingOptions<'static>,      ) -> bool      where @@ -205,7 +206,7 @@ impl AsyncDIContainer      }      async fn set_binding<Interface>( -        self: &Arc<Self>, +        &self,          binding_options: BindingOptions<'static>,          provider: Box<dyn IAsyncProvider<Self>>,      ) where @@ -218,7 +219,7 @@ impl AsyncDIContainer      }      async fn remove_binding<Interface>( -        self: &Arc<Self>, +        &self,          binding_options: BindingOptions<'static>,      ) -> Option<Box<dyn IAsyncProvider<Self>>>      where @@ -234,7 +235,7 @@ impl AsyncDIContainer  impl AsyncDIContainer  {      async fn handle_binding_providable<Interface>( -        self: &Arc<Self>, +        &self,          binding_providable: AsyncProvidable<Self>,      ) -> Result<SomePtr<Interface>, AsyncDIContainerError>      where @@ -299,9 +300,7 @@ impl AsyncDIContainer                          }                      })?; -                Ok(SomePtr::ThreadsafeFactory( -                    factory.call(self.clone()).into(), -                )) +                Ok(SomePtr::ThreadsafeFactory(factory.call(self).into()))              }              #[cfg(feature = "factory")]              AsyncProvidable::DefaultFactory(binding) => { @@ -317,7 +316,7 @@ impl AsyncDIContainer                      DefaultFactoryFn<Interface>,                  >(binding, "default factory")?; -                Ok(SomePtr::Transient(default_factory.call(self.clone())())) +                Ok(SomePtr::Transient(default_factory.call(self)()))              }              #[cfg(feature = "factory")]              AsyncProvidable::AsyncDefaultFactory(binding) => { @@ -338,9 +337,7 @@ impl AsyncDIContainer                      binding, "async default factory"                  )?; -                Ok(SomePtr::Transient( -                    async_default_factory.call(self.clone())().await, -                )) +                Ok(SomePtr::Transient(async_default_factory.call(self)().await))              }          }      } @@ -368,7 +365,7 @@ impl AsyncDIContainer      }      async fn get_binding_providable<Interface>( -        self: &Arc<Self>, +        &self,          binding_options: BindingOptions<'static>,          dependency_history: DependencyHistory,      ) -> Result<AsyncProvidable<Self>, AsyncDIContainerError> @@ -644,21 +641,13 @@ mod tests          let mut mock_provider = MockAsyncProvider::new();          mock_provider.expect_do_clone().returning(|| { -            type FactoryFunc = Box< -                (dyn Fn<(Vec<i128>,), Output = TransientPtr<dyn IUserManager>> + Send + Sync) -            >; -              let mut inner_mock_provider = MockAsyncProvider::new(); -            let factory_func: &'static (dyn Fn< -                (Arc<AsyncDIContainer>,), -                Output = FactoryFunc> + Send + Sync) = &|_| { +            let factory_func = &|_: &AsyncDIContainer| {                  Box::new(|users| { -                    let user_manager: TransientPtr<dyn IUserManager> = -                        TransientPtr::new(UserManager::new(users)); - -                    user_manager -                }) +                    TransientPtr::new(UserManager::new(users)) +                        as TransientPtr<dyn IUserManager> +                }) as Box<IUserManagerFactory>              };              inner_mock_provider.expect_provide().returning(|_, _| { @@ -672,16 +661,11 @@ mod tests              Box::new(inner_mock_provider)          }); -        { -            di_container -                .binding_storage -                .lock() -                .await -                .set::<IUserManagerFactory>( -                    BindingOptions::new(), -                    Box::new(mock_provider), -                ); -        } +        di_container +            .binding_storage +            .lock() +            .await +            .set::<IUserManagerFactory>(BindingOptions::new(), Box::new(mock_provider));          di_container              .get::<IUserManagerFactory>() @@ -743,21 +727,13 @@ mod tests          let mut mock_provider = MockAsyncProvider::new();          mock_provider.expect_do_clone().returning(|| { -            type FactoryFunc = Box< -                (dyn Fn<(Vec<i128>,), Output = TransientPtr<dyn IUserManager>> + Send + Sync) -            >; -              let mut inner_mock_provider = MockAsyncProvider::new(); -            let factory_func: &'static (dyn Fn< -                (Arc<AsyncDIContainer>,), -                Output = FactoryFunc> + Send + Sync) = &|_| { +            let factory_func = &|_: &AsyncDIContainer| {                  Box::new(|users| { -                    let user_manager: TransientPtr<dyn IUserManager> = -                        TransientPtr::new(UserManager::new(users)); - -                    user_manager -                }) +                    TransientPtr::new(UserManager::new(users)) +                        as TransientPtr<dyn IUserManager> +                }) as Box<IUserManagerFactory>              };              inner_mock_provider.expect_provide().returning(|_, _| { | 
