diff options
Diffstat (limited to 'src/di_container')
-rw-r--r-- | src/di_container/asynchronous/binding/builder.rs | 59 | ||||
-rw-r--r-- | src/di_container/asynchronous/binding/scope_configurator.rs | 9 | ||||
-rw-r--r-- | src/di_container/asynchronous/binding/when_configurator.rs | 9 | ||||
-rw-r--r-- | src/di_container/asynchronous/mod.rs | 63 | ||||
-rw-r--r-- | src/di_container/binding_storage.rs | 170 | ||||
-rw-r--r-- | src/di_container/blocking/binding/builder.rs | 44 | ||||
-rw-r--r-- | src/di_container/blocking/binding/scope_configurator.rs | 13 | ||||
-rw-r--r-- | src/di_container/blocking/binding/when_configurator.rs | 9 | ||||
-rw-r--r-- | src/di_container/blocking/mod.rs | 63 | ||||
-rw-r--r-- | src/di_container/mod.rs | 4 |
10 files changed, 247 insertions, 196 deletions
diff --git a/src/di_container/asynchronous/binding/builder.rs b/src/di_container/asynchronous/binding/builder.rs index 5862d63..83a1efb 100644 --- a/src/di_container/asynchronous/binding/builder.rs +++ b/src/di_container/asynchronous/binding/builder.rs @@ -9,6 +9,7 @@ use crate::di_container::asynchronous::binding::scope_configurator::AsyncBinding #[cfg(feature = "factory")] use crate::di_container::asynchronous::binding::when_configurator::AsyncBindingWhenConfigurator; use crate::di_container::asynchronous::IAsyncDIContainer; +use crate::di_container::BindingOptions; use crate::errors::async_di_container::AsyncBindingBuilderError; use crate::interfaces::async_injectable::AsyncInjectable; use crate::util::use_double; @@ -104,7 +105,11 @@ where where Implementation: AsyncInjectable<DIContainerType>, { - if self.di_container.has_binding::<Interface>(None).await { + if self + .di_container + .has_binding::<Interface>(BindingOptions::new()) + .await + { return Err(AsyncBindingBuilderError::BindingAlreadyExists(type_name::< Interface, >( @@ -189,7 +194,11 @@ where use crate::private::castable_factory::threadsafe::ThreadsafeCastableFactory; use crate::provider::r#async::AsyncFactoryVariant; - if self.di_container.has_binding::<Interface>(None).await { + if self + .di_container + .has_binding::<Interface>(BindingOptions::new()) + .await + { return Err(AsyncBindingBuilderError::BindingAlreadyExists(type_name::< Interface, >( @@ -200,7 +209,7 @@ where self.di_container .set_binding::<Interface>( - None, + BindingOptions::new(), Box::new(crate::provider::r#async::AsyncFactoryProvider::new( crate::ptr::ThreadsafeFactoryPtr::new(factory_impl), AsyncFactoryVariant::Normal, @@ -292,7 +301,11 @@ where use crate::private::castable_factory::threadsafe::ThreadsafeCastableFactory; use crate::provider::r#async::AsyncFactoryVariant; - if self.di_container.has_binding::<Interface>(None).await { + if self + .di_container + .has_binding::<Interface>(BindingOptions::new()) + .await + { return Err(AsyncBindingBuilderError::BindingAlreadyExists(type_name::< Interface, >( @@ -303,7 +316,7 @@ where self.di_container .set_binding::<Interface>( - None, + BindingOptions::new(), Box::new(crate::provider::r#async::AsyncFactoryProvider::new( crate::ptr::ThreadsafeFactoryPtr::new(factory_impl), AsyncFactoryVariant::Normal, @@ -382,7 +395,11 @@ where use crate::private::castable_factory::threadsafe::ThreadsafeCastableFactory; use crate::provider::r#async::AsyncFactoryVariant; - if self.di_container.has_binding::<Interface>(None).await { + if self + .di_container + .has_binding::<Interface>(BindingOptions::new()) + .await + { return Err(AsyncBindingBuilderError::BindingAlreadyExists(type_name::< Interface, >( @@ -393,7 +410,7 @@ where self.di_container .set_binding::<Interface>( - None, + BindingOptions::new(), Box::new(crate::provider::r#async::AsyncFactoryProvider::new( crate::ptr::ThreadsafeFactoryPtr::new(factory_impl), AsyncFactoryVariant::Default, @@ -477,7 +494,11 @@ where use crate::private::castable_factory::threadsafe::ThreadsafeCastableFactory; use crate::provider::r#async::AsyncFactoryVariant; - if self.di_container.has_binding::<Interface>(None).await { + if self + .di_container + .has_binding::<Interface>(BindingOptions::new()) + .await + { return Err(AsyncBindingBuilderError::BindingAlreadyExists(type_name::< Interface, >( @@ -488,7 +509,7 @@ where self.di_container .set_binding::<Interface>( - None, + BindingOptions::new(), Box::new(crate::provider::r#async::AsyncFactoryProvider::new( crate::ptr::ThreadsafeFactoryPtr::new(factory_impl), AsyncFactoryVariant::AsyncDefault, @@ -519,13 +540,13 @@ mod tests di_container_mock .expect_has_binding::<dyn subjects_async::IUserManager>() - .with(eq(None)) + .with(eq(BindingOptions::new())) .return_once(|_name| false) .once(); di_container_mock .expect_set_binding::<dyn subjects_async::IUserManager>() - .withf(|name, _provider| name.is_none()) + .withf(|binding_options, _provider| binding_options.name.is_none()) .return_once(|_name, _provider| ()) .once(); @@ -562,13 +583,13 @@ mod tests di_container_mock .expect_has_binding::<IUserManagerFactory>() - .with(eq(None)) + .with(eq(BindingOptions::new())) .return_once(|_name| false) .once(); di_container_mock .expect_set_binding::<IUserManagerFactory>() - .withf(|name, _provider| name.is_none()) + .withf(|binding_options, _provider| binding_options.name.is_none()) .return_once(|_name, _provider| ()) .once(); @@ -613,13 +634,13 @@ mod tests di_container_mock .expect_has_binding::<IUserManagerFactory>() - .with(eq(None)) + .with(eq(BindingOptions::new())) .return_once(|_name| false) .once(); di_container_mock .expect_set_binding::<IUserManagerFactory>() - .withf(|name, _provider| name.is_none()) + .withf(|binding_options, _provider| binding_options.name.is_none()) .return_once(|_name, _provider| ()) .once(); @@ -659,13 +680,13 @@ mod tests di_container_mock .expect_has_binding::<dyn subjects_async::IUserManager>() - .with(eq(None)) + .with(eq(BindingOptions::new())) .return_once(|_name| false) .once(); di_container_mock .expect_set_binding::<dyn subjects_async::IUserManager>() - .withf(|name, _provider| name.is_none()) + .withf(|binding_options, _provider| binding_options.name.is_none()) .return_once(|_name, _provider| ()) .once(); @@ -706,13 +727,13 @@ mod tests di_container_mock .expect_has_binding::<dyn subjects_async::IUserManager>() - .with(eq(None)) + .with(eq(BindingOptions::new())) .return_once(|_name| false) .once(); di_container_mock .expect_set_binding::<dyn subjects_async::IUserManager>() - .withf(|name, _provider| name.is_none()) + .withf(|binding_options, _provider| binding_options.name.is_none()) .return_once(|_name, _provider| ()) .once(); diff --git a/src/di_container/asynchronous/binding/scope_configurator.rs b/src/di_container/asynchronous/binding/scope_configurator.rs index 0b5bad8..f10bb48 100644 --- a/src/di_container/asynchronous/binding/scope_configurator.rs +++ b/src/di_container/asynchronous/binding/scope_configurator.rs @@ -6,6 +6,7 @@ use std::sync::Arc; use crate::di_container::asynchronous::binding::when_configurator::AsyncBindingWhenConfigurator; use crate::di_container::asynchronous::IAsyncDIContainer; +use crate::di_container::BindingOptions; use crate::errors::async_di_container::AsyncBindingScopeConfiguratorError; use crate::interfaces::async_injectable::AsyncInjectable; use crate::provider::r#async::{AsyncSingletonProvider, AsyncTransientTypeProvider}; @@ -85,7 +86,7 @@ where self.di_container .set_binding::<Interface>( - None, + BindingOptions::new(), Box::new(AsyncSingletonProvider::new(singleton)), ) .await; @@ -97,7 +98,7 @@ where { self.di_container .set_binding::<Interface>( - None, + BindingOptions::new(), Box::new( AsyncTransientTypeProvider::<Implementation, DIContainerType>::new(), ), @@ -121,7 +122,7 @@ mod tests di_container_mock .expect_set_binding::<dyn subjects_async::IUserManager>() - .withf(|name, _provider| name.is_none()) + .withf(|binding_options, _provider| binding_options.name.is_none()) .return_once(|_name, _provider| ()) .once(); @@ -143,7 +144,7 @@ mod tests di_container_mock .expect_set_binding::<dyn subjects_async::IUserManager>() - .withf(|name, _provider| name.is_none()) + .withf(|binding_options, _provider| binding_options.name.is_none()) .return_once(|_name, _provider| ()) .once(); diff --git a/src/di_container/asynchronous/binding/when_configurator.rs b/src/di_container/asynchronous/binding/when_configurator.rs index d08239e..4521178 100644 --- a/src/di_container/asynchronous/binding/when_configurator.rs +++ b/src/di_container/asynchronous/binding/when_configurator.rs @@ -6,6 +6,7 @@ use std::marker::PhantomData; use std::sync::Arc; use crate::di_container::asynchronous::IAsyncDIContainer; +use crate::di_container::BindingOptions; use crate::errors::async_di_container::AsyncBindingWhenConfiguratorError; /// When configurator for a binding for type `Interface` inside a [`IAsyncDIContainer`]. @@ -45,7 +46,7 @@ where { let binding = self .di_container - .remove_binding::<Interface>(None) + .remove_binding::<Interface>(BindingOptions::new()) .await .map_or_else( || { @@ -57,7 +58,7 @@ where )?; self.di_container - .set_binding::<Interface>(Some(name), binding) + .set_binding::<Interface>(BindingOptions::new().name(name), binding) .await; Ok(()) @@ -81,13 +82,13 @@ mod tests di_container_mock .expect_remove_binding::<dyn subjects_async::INumber>() - .with(eq(None)) + .with(eq(BindingOptions::new())) .return_once(|_name| Some(Box::new(MockIAsyncProvider::new()))) .once(); di_container_mock .expect_set_binding::<dyn subjects_async::INumber>() - .withf(|name, _provider| name == &Some("awesome")) + .withf(|binding_options, _provider| binding_options.name == Some("awesome")) .return_once(|_name, _provider| ()) .once(); diff --git a/src/di_container/asynchronous/mod.rs b/src/di_container/asynchronous/mod.rs index e5f7f5d..8d67b99 100644 --- a/src/di_container/asynchronous/mod.rs +++ b/src/di_container/asynchronous/mod.rs @@ -235,10 +235,7 @@ impl IAsyncDIContainer for AsyncDIContainer { Box::pin(async move { let binding_providable = self - .get_binding_providable::<Interface>( - binding_options.name, - dependency_history, - ) + .get_binding_providable::<Interface>(binding_options, dependency_history) .await?; self.handle_binding_providable(binding_providable).await @@ -249,16 +246,22 @@ impl IAsyncDIContainer for AsyncDIContainer #[async_trait] impl details::DIContainerInternals for AsyncDIContainer { - async fn has_binding<Interface>(self: &Arc<Self>, name: Option<&'static str>) -> bool + async fn has_binding<Interface>( + self: &Arc<Self>, + binding_options: BindingOptions<'static>, + ) -> bool where Interface: ?Sized + 'static, { - self.binding_storage.lock().await.has::<Interface>(name) + self.binding_storage + .lock() + .await + .has::<Interface>(binding_options) } async fn set_binding<Interface>( self: &Arc<Self>, - name: Option<&'static str>, + binding_options: BindingOptions<'static>, provider: Box<dyn IAsyncProvider<Self>>, ) where Interface: 'static + ?Sized, @@ -266,17 +269,20 @@ impl details::DIContainerInternals for AsyncDIContainer self.binding_storage .lock() .await - .set::<Interface>(name, provider); + .set::<Interface>(binding_options, provider); } async fn remove_binding<Interface>( self: &Arc<Self>, - name: Option<&'static str>, + binding_options: BindingOptions<'static>, ) -> Option<Box<dyn IAsyncProvider<Self>>> where Interface: 'static + ?Sized, { - self.binding_storage.lock().await.remove::<Interface>(name) + self.binding_storage + .lock() + .await + .remove::<Interface>(binding_options) } } @@ -411,7 +417,7 @@ impl AsyncDIContainer async fn get_binding_providable<Interface>( self: &Arc<Self>, - name: Option<&'static str>, + binding_options: BindingOptions<'static>, dependency_history: DependencyHistory, ) -> Result<AsyncProvidable<Self>, AsyncDIContainerError> where @@ -423,12 +429,12 @@ impl AsyncDIContainer let bindings_lock = self.binding_storage.lock().await; provider = bindings_lock - .get::<Interface>(name) + .get::<Interface>(binding_options.clone()) .map_or_else( || { Err(AsyncDIContainerError::BindingNotFound { interface: type_name::<Interface>(), - name, + name: binding_options.name, }) }, Ok, @@ -452,6 +458,7 @@ pub(crate) mod details use async_trait::async_trait; + use crate::di_container::BindingOptions; use crate::provider::r#async::IAsyncProvider; #[async_trait] @@ -459,21 +466,21 @@ pub(crate) mod details { async fn has_binding<Interface>( self: &Arc<Self>, - name: Option<&'static str>, + binding_options: BindingOptions<'static>, ) -> bool where Interface: ?Sized + 'static; async fn set_binding<Interface>( self: &Arc<Self>, - name: Option<&'static str>, + binding_options: BindingOptions<'static>, provider: Box<dyn IAsyncProvider<Self>>, ) where Interface: 'static + ?Sized; async fn remove_binding<Interface>( self: &Arc<Self>, - name: Option<&'static str>, + binding_options: BindingOptions<'static>, ) -> Option<Box<dyn IAsyncProvider<Self>>> where Interface: 'static + ?Sized; @@ -514,7 +521,10 @@ mod tests .binding_storage .lock() .await - .set::<dyn subjects_async::IUserManager>(None, Box::new(mock_provider)); + .set::<dyn subjects_async::IUserManager>( + BindingOptions::new(), + Box::new(mock_provider), + ); } di_container @@ -550,7 +560,7 @@ mod tests .lock() .await .set::<dyn subjects_async::IUserManager>( - Some("special"), + BindingOptions::new().name("special"), Box::new(mock_provider), ); } @@ -591,7 +601,10 @@ mod tests .binding_storage .lock() .await - .set::<dyn subjects_async::INumber>(None, Box::new(mock_provider)); + .set::<dyn subjects_async::INumber>( + BindingOptions::new(), + Box::new(mock_provider), + ); } let first_number_rc = di_container @@ -640,7 +653,7 @@ mod tests .lock() .await .set::<dyn subjects_async::INumber>( - Some("cool"), + BindingOptions::new().name("cool"), Box::new(mock_provider), ); } @@ -747,7 +760,10 @@ mod tests .binding_storage .lock() .await - .set::<IUserManagerFactory>(None, Box::new(mock_provider)); + .set::<IUserManagerFactory>( + BindingOptions::new(), + Box::new(mock_provider), + ); } di_container @@ -843,7 +859,10 @@ mod tests .binding_storage .lock() .await - .set::<IUserManagerFactory>(Some("special"), Box::new(mock_provider)); + .set::<IUserManagerFactory>( + BindingOptions::new().name("special"), + Box::new(mock_provider), + ); } di_container diff --git a/src/di_container/binding_storage.rs b/src/di_container/binding_storage.rs index 3c3c565..2451791 100644 --- a/src/di_container/binding_storage.rs +++ b/src/di_container/binding_storage.rs @@ -2,11 +2,13 @@ use std::any::TypeId; use ahash::AHashMap; +use crate::di_container::BindingOptions; + pub struct DIContainerBindingStorage<Provider> where Provider: 'static + ?Sized, { - inner: AHashMap<BindingIdentification<'static>, Box<Provider>>, + inner: AHashMap<BindingId<'static>, Box<Provider>>, } impl<Provider> DIContainerBindingStorage<Provider> @@ -21,69 +23,64 @@ where } #[allow(clippy::borrowed_box)] - pub fn get<'me, Interface>( - &'me self, - name: Option<&'me str>, - ) -> Option<&'me Box<Provider>> + pub fn get<'this, Interface>( + &'this self, + options: BindingOptions<'this>, + ) -> Option<&'this Box<Provider>> where Interface: 'static + ?Sized, { - let interface_typeid = TypeId::of::<Interface>(); - - self.inner.get(&BindingIdentification { - type_id: interface_typeid, - name, - }) + self.inner.get(&BindingId::new::<Interface>(options)) } - pub fn set<Interface>(&mut self, name: Option<&'static str>, provider: Box<Provider>) - where + pub fn set<Interface>( + &mut self, + options: BindingOptions<'static>, + provider: Box<Provider>, + ) where Interface: 'static + ?Sized, { - let interface_typeid = TypeId::of::<Interface>(); - - self.inner.insert( - BindingIdentification { - type_id: interface_typeid, - name, - }, - provider, - ); + self.inner + .insert(BindingId::new::<Interface>(options), provider); } pub fn remove<Interface>( &mut self, - name: Option<&'static str>, + options: BindingOptions<'static>, ) -> Option<Box<Provider>> where Interface: 'static + ?Sized, { - let interface_typeid = TypeId::of::<Interface>(); - - self.inner.remove(&BindingIdentification { - type_id: interface_typeid, - name, - }) + self.inner.remove(&BindingId::new::<Interface>(options)) } - pub fn has<Interface>(&self, name: Option<&'static str>) -> bool + pub fn has<Interface>(&self, options: BindingOptions) -> bool where Interface: 'static + ?Sized, { - let interface_typeid = TypeId::of::<Interface>(); - - self.inner.contains_key(&BindingIdentification { - type_id: interface_typeid, - name, - }) + self.inner + .contains_key(&BindingId::new::<Interface>(options)) } } #[derive(Debug, PartialEq, Eq, Hash)] -struct BindingIdentification<'a> +struct BindingId<'opts> { type_id: TypeId, - name: Option<&'a str>, + options: BindingOptions<'opts>, +} + +impl<'opts> BindingId<'opts> +{ + fn new<Interface>(options: BindingOptions<'opts>) -> Self + where + Interface: ?Sized + 'static, + { + Self { + type_id: TypeId::of::<Interface>(), + options, + } + } } #[cfg(test)] @@ -121,15 +118,12 @@ mod tests DIContainerBindingStorage::<dyn subjects::SomeProvider>::new(); binding_map.inner.insert( - BindingIdentification { - type_id: TypeId::of::<Interface>(), - name: None, - }, + BindingId::new::<Interface>(BindingOptions::new()), Box::new(subjects::SomeProviderImpl { id: 20 }), ); assert!(binding_map - .get::<Interface>(None) + .get::<Interface>(BindingOptions::new()) .map_or_else(|| false, |provider| provider.get_id() == 20)); } @@ -142,18 +136,17 @@ mod tests DIContainerBindingStorage::<dyn subjects::SomeProvider>::new(); binding_map.inner.insert( - BindingIdentification { - type_id: TypeId::of::<Interface>(), - name: Some("hello"), - }, + BindingId::new::<Interface>(BindingOptions::new().name("hello")), Box::new(subjects::SomeProviderImpl { id: 11 }), ); assert!(binding_map - .get::<Interface>(Some("hello")) + .get::<Interface>(BindingOptions::new().name("hello")) .map_or_else(|| false, |provider| provider.get_id() == 11)); - assert!(binding_map.get::<Interface>(None).is_none()); + assert!(binding_map + .get::<Interface>(BindingOptions::new()) + .is_none()); } #[test] @@ -164,17 +157,16 @@ mod tests let mut binding_map = DIContainerBindingStorage::<dyn subjects::SomeProvider>::new(); - binding_map - .set::<Interface>(None, Box::new(subjects::SomeProviderImpl { id: 65 })); + binding_map.set::<Interface>( + BindingOptions::new(), + Box::new(subjects::SomeProviderImpl { id: 65 }), + ); - let expected_key = &BindingIdentification { - type_id: TypeId::of::<Interface>(), - name: None, - }; + let expected_key = BindingId::new::<Interface>(BindingOptions::new()); - assert!(binding_map.inner.contains_key(expected_key)); + assert!(binding_map.inner.contains_key(&expected_key)); - assert_eq!(binding_map.inner[expected_key].get_id(), 65); + assert_eq!(binding_map.inner[&expected_key].get_id(), 65); } #[test] @@ -186,18 +178,16 @@ mod tests DIContainerBindingStorage::<dyn subjects::SomeProvider>::new(); binding_map.set::<Interface>( - Some("special"), + BindingOptions::new().name("special"), Box::new(subjects::SomeProviderImpl { id: 3 }), ); - let expected_key = &BindingIdentification { - type_id: TypeId::of::<Interface>(), - name: Some("special"), - }; + let expected_key = + BindingId::new::<Interface>(BindingOptions::new().name("special")); - assert!(binding_map.inner.contains_key(expected_key)); + assert!(binding_map.inner.contains_key(&expected_key)); - assert_eq!(binding_map.inner[expected_key].get_id(), 3); + assert_eq!(binding_map.inner[&expected_key].get_id(), 3); } #[test] @@ -209,21 +199,15 @@ mod tests DIContainerBindingStorage::<dyn subjects::SomeProvider>::new(); binding_map.inner.insert( - BindingIdentification { - type_id: TypeId::of::<Interface>(), - name: None, - }, + BindingId::new::<Interface>(BindingOptions::new()), Box::new(subjects::SomeProviderImpl { id: 103 }), ); - binding_map.remove::<Interface>(None); - - let expected_key = &BindingIdentification { - type_id: TypeId::of::<Interface>(), - name: None, - }; + binding_map.remove::<Interface>(BindingOptions::new()); - assert!(!binding_map.inner.contains_key(expected_key)); + assert!(!binding_map + .inner + .contains_key(&BindingId::new::<Interface>(BindingOptions::new()))); } #[test] @@ -235,21 +219,17 @@ mod tests DIContainerBindingStorage::<dyn subjects::SomeProvider>::new(); binding_map.inner.insert( - BindingIdentification { - type_id: TypeId::of::<Interface>(), - name: Some("cool"), - }, + BindingId::new::<Interface>(BindingOptions::new().name("cool")), Box::new(subjects::SomeProviderImpl { id: 42 }), ); - binding_map.remove::<Interface>(Some("cool")); + binding_map.remove::<Interface>(BindingOptions::new().name("cool")); - let expected_key = &BindingIdentification { - type_id: TypeId::of::<Interface>(), - name: Some("cool"), - }; - - assert!(!binding_map.inner.contains_key(expected_key)); + assert!( + !binding_map.inner.contains_key(&BindingId::new::<Interface>( + BindingOptions::new().name("cool") + )) + ); } #[test] @@ -260,17 +240,14 @@ mod tests let mut binding_map = DIContainerBindingStorage::<dyn subjects::SomeProvider>::new(); - assert!(!binding_map.has::<Interface>(None)); + assert!(!binding_map.has::<Interface>(BindingOptions::new())); binding_map.inner.insert( - BindingIdentification { - type_id: TypeId::of::<Interface>(), - name: None, - }, + BindingId::new::<Interface>(BindingOptions::new()), Box::new(subjects::SomeProviderImpl { id: 103 }), ); - assert!(binding_map.has::<Interface>(None)); + assert!(binding_map.has::<Interface>(BindingOptions::new())); } #[test] @@ -281,16 +258,13 @@ mod tests let mut binding_map = DIContainerBindingStorage::<dyn subjects::SomeProvider>::new(); - assert!(!binding_map.has::<Interface>(Some("awesome"))); + assert!(!binding_map.has::<Interface>(BindingOptions::new().name("awesome"))); binding_map.inner.insert( - BindingIdentification { - type_id: TypeId::of::<Interface>(), - name: Some("awesome"), - }, + BindingId::new::<Interface>(BindingOptions::new().name("awesome")), Box::new(subjects::SomeProviderImpl { id: 101 }), ); - assert!(binding_map.has::<Interface>(Some("awesome"))); + assert!(binding_map.has::<Interface>(BindingOptions::new().name("awesome"))); } } diff --git a/src/di_container/blocking/binding/builder.rs b/src/di_container/blocking/binding/builder.rs index 0c323ec..577f034 100644 --- a/src/di_container/blocking/binding/builder.rs +++ b/src/di_container/blocking/binding/builder.rs @@ -9,6 +9,7 @@ use crate::di_container::blocking::binding::scope_configurator::BindingScopeConf #[cfg(feature = "factory")] use crate::di_container::blocking::binding::when_configurator::BindingWhenConfigurator; use crate::di_container::blocking::IDIContainer; +use crate::di_container::BindingOptions; use crate::errors::di_container::BindingBuilderError; use crate::interfaces::injectable::Injectable; use crate::util::use_double; @@ -99,7 +100,10 @@ where Implementation: Injectable<DIContainerType>, { { - if self.di_container.has_binding::<Interface>(None) { + if self + .di_container + .has_binding::<Interface>(BindingOptions::new()) + { return Err(BindingBuilderError::BindingAlreadyExists(type_name::< Interface, >( @@ -197,7 +201,10 @@ where { use crate::private::castable_factory::blocking::CastableFactory; - if self.di_container.has_binding::<Interface>(None) { + if self + .di_container + .has_binding::<Interface>(BindingOptions::new()) + { return Err(BindingBuilderError::BindingAlreadyExists(type_name::< Interface, >())); @@ -206,7 +213,7 @@ where let factory_impl = CastableFactory::new(factory_func); self.di_container.set_binding::<Interface>( - None, + BindingOptions::new(), Box::new(crate::provider::blocking::FactoryProvider::new( crate::ptr::FactoryPtr::new(factory_impl), false, @@ -286,7 +293,10 @@ where { use crate::private::castable_factory::blocking::CastableFactory; - if self.di_container.has_binding::<Interface>(None) { + if self + .di_container + .has_binding::<Interface>(BindingOptions::new()) + { return Err(BindingBuilderError::BindingAlreadyExists(type_name::< Interface, >())); @@ -295,7 +305,7 @@ where let factory_impl = CastableFactory::new(factory_func); self.di_container.set_binding::<Interface>( - None, + BindingOptions::new(), Box::new(crate::provider::blocking::FactoryProvider::new( crate::ptr::FactoryPtr::new(factory_impl), true, @@ -324,14 +334,14 @@ mod tests mock_di_container .expect_has_binding::<dyn subjects::INumber>() - .with(eq(None)) - .return_once(|_name| false) + .with(eq(BindingOptions::new())) + .return_once(|_options| false) .once(); mock_di_container .expect_set_binding::<dyn subjects::INumber>() - .withf(|name, _provider| name.is_none()) - .return_once(|_name, _provider| ()) + .withf(|options, _provider| options.name.is_none()) + .return_once(|_options, _provider| ()) .once(); let binding_builder = @@ -361,14 +371,14 @@ mod tests mock_di_container .expect_has_binding::<IUserManagerFactory>() - .with(eq(None)) - .return_once(|_name| false) + .with(eq(BindingOptions::new())) + .return_once(|_| false) .once(); mock_di_container .expect_set_binding::<IUserManagerFactory>() - .withf(|name, _provider| name.is_none()) - .return_once(|_name, _provider| ()) + .withf(|options, _provider| options.name.is_none()) + .return_once(|_, _provider| ()) .once(); let binding_builder = @@ -404,14 +414,14 @@ mod tests mock_di_container .expect_has_binding::<dyn subjects::IUserManager>() - .with(eq(None)) - .return_once(|_name| false) + .with(eq(BindingOptions::new())) + .return_once(|_| false) .once(); mock_di_container .expect_set_binding::<dyn subjects::IUserManager>() - .withf(|name, _provider| name.is_none()) - .return_once(|_name, _provider| ()) + .withf(|options, _provider| options.name.is_none()) + .return_once(|_, _provider| ()) .once(); let binding_builder = diff --git a/src/di_container/blocking/binding/scope_configurator.rs b/src/di_container/blocking/binding/scope_configurator.rs index 0aefa93..0fcdfdf 100644 --- a/src/di_container/blocking/binding/scope_configurator.rs +++ b/src/di_container/blocking/binding/scope_configurator.rs @@ -6,6 +6,7 @@ use std::rc::Rc; use crate::di_container::blocking::binding::when_configurator::BindingWhenConfigurator; use crate::di_container::blocking::IDIContainer; +use crate::di_container::BindingOptions; use crate::errors::di_container::BindingScopeConfiguratorError; use crate::interfaces::injectable::Injectable; use crate::provider::blocking::{SingletonProvider, TransientTypeProvider}; @@ -81,8 +82,10 @@ where .map_err(BindingScopeConfiguratorError::SingletonResolveFailed)?, ); - self.di_container - .set_binding::<Interface>(None, Box::new(SingletonProvider::new(singleton))); + self.di_container.set_binding::<Interface>( + BindingOptions::new(), + Box::new(SingletonProvider::new(singleton)), + ); Ok(BindingWhenConfigurator::new(self.di_container)) } @@ -90,7 +93,7 @@ where pub(crate) fn set_in_transient_scope(&self) { self.di_container.set_binding::<Interface>( - None, + BindingOptions::new(), Box::new(TransientTypeProvider::<Implementation, DIContainerType>::new()), ); } @@ -110,7 +113,7 @@ mod tests di_container_mock .expect_set_binding::<dyn subjects::IUserManager>() - .withf(|name, _provider| name.is_none()) + .withf(|options, _provider| options.name.is_none()) .return_once(|_name, _provider| ()) .once(); @@ -131,7 +134,7 @@ mod tests di_container_mock .expect_set_binding::<dyn subjects::IUserManager>() - .withf(|name, _provider| name.is_none()) + .withf(|options, _provider| options.name.is_none()) .return_once(|_name, _provider| ()) .once(); diff --git a/src/di_container/blocking/binding/when_configurator.rs b/src/di_container/blocking/binding/when_configurator.rs index fcef377..52b23ff 100644 --- a/src/di_container/blocking/binding/when_configurator.rs +++ b/src/di_container/blocking/binding/when_configurator.rs @@ -6,6 +6,7 @@ use std::marker::PhantomData; use std::rc::Rc; use crate::di_container::blocking::IDIContainer; +use crate::di_container::BindingOptions; use crate::errors::di_container::BindingWhenConfiguratorError; /// When configurator for a binding for type `Interface` inside a [`IDIContainer`]. @@ -45,7 +46,7 @@ where { let binding = self .di_container - .remove_binding::<Interface>(None) + .remove_binding::<Interface>(BindingOptions::new()) .map_or_else( || { Err(BindingWhenConfiguratorError::BindingNotFound(type_name::< @@ -57,7 +58,7 @@ where )?; self.di_container - .set_binding::<Interface>(Some(name), binding); + .set_binding::<Interface>(BindingOptions::new().name(name), binding); Ok(()) } @@ -79,13 +80,13 @@ mod tests di_container_mock .expect_remove_binding::<dyn subjects::INumber>() - .with(eq(None)) + .with(eq(BindingOptions::new())) .return_once(|_name| Some(Box::new(MockIProvider::new()))) .once(); di_container_mock .expect_set_binding::<dyn subjects::INumber>() - .withf(|name, _provider| name == &Some("cool")) + .withf(|options, _provider| options.name == Some("cool")) .return_once(|_name, _provider| ()) .once(); diff --git a/src/di_container/blocking/mod.rs b/src/di_container/blocking/mod.rs index 5b0acc8..27ea0fb 100644 --- a/src/di_container/blocking/mod.rs +++ b/src/di_container/blocking/mod.rs @@ -210,10 +210,8 @@ impl IDIContainer for DIContainer where Interface: 'static + ?Sized, { - let binding_providable = self.get_binding_providable::<Interface>( - binding_options.name, - dependency_history, - )?; + let binding_providable = self + .get_binding_providable::<Interface>(binding_options, dependency_history)?; #[cfg(feature = "factory")] return self.handle_binding_providable(binding_providable); @@ -225,33 +223,37 @@ impl IDIContainer for DIContainer impl details::DIContainerInternals for DIContainer { - fn has_binding<Interface>(self: &Rc<Self>, name: Option<&'static str>) -> bool + fn has_binding<Interface>(self: &Rc<Self>, binding_options: BindingOptions) -> bool where Interface: ?Sized + 'static, { - self.binding_storage.borrow().has::<Interface>(name) + self.binding_storage + .borrow() + .has::<Interface>(binding_options) } fn set_binding<Interface>( self: &Rc<Self>, - name: Option<&'static str>, + binding_options: BindingOptions<'static>, provider: Box<dyn IProvider<Self>>, ) where Interface: 'static + ?Sized, { self.binding_storage .borrow_mut() - .set::<Interface>(name, provider); + .set::<Interface>(binding_options, provider); } fn remove_binding<Interface>( self: &Rc<Self>, - name: Option<&'static str>, + binding_options: BindingOptions<'static>, ) -> Option<Box<dyn IProvider<Self>>> where Interface: 'static + ?Sized, { - self.binding_storage.borrow_mut().remove::<Interface>(name) + self.binding_storage + .borrow_mut() + .remove::<Interface>(binding_options) } } @@ -316,15 +318,17 @@ impl DIContainer fn get_binding_providable<Interface>( self: &Rc<Self>, - name: Option<&str>, + binding_options: BindingOptions, dependency_history: DependencyHistory, ) -> Result<Providable<Self>, DIContainerError> where Interface: 'static + ?Sized, { + let name = binding_options.name; + self.binding_storage .borrow() - .get::<Interface>(name) + .get::<Interface>(binding_options) .map_or_else( || { Err(DIContainerError::BindingNotFound { @@ -346,24 +350,29 @@ pub(crate) mod details { use std::rc::Rc; + use crate::di_container::blocking::BindingOptionsWithLt; + use crate::di_container::BindingOptions; use crate::provider::blocking::IProvider; pub trait DIContainerInternals { - fn has_binding<Interface>(self: &Rc<Self>, name: Option<&'static str>) -> bool + fn has_binding<Interface>( + self: &Rc<Self>, + binding_options: BindingOptionsWithLt, + ) -> bool where Interface: ?Sized + 'static; fn set_binding<Interface>( self: &Rc<Self>, - name: Option<&'static str>, + binding_options: BindingOptions<'static>, provider: Box<dyn IProvider<Self>>, ) where Interface: 'static + ?Sized; fn remove_binding<Interface>( self: &Rc<Self>, - name: Option<&'static str>, + binding_options: BindingOptions<'static>, ) -> Option<Box<dyn IProvider<Self>>> where Interface: 'static + ?Sized; @@ -395,7 +404,10 @@ mod tests di_container .binding_storage .borrow_mut() - .set::<dyn subjects::IUserManager>(None, Box::new(mock_provider)); + .set::<dyn subjects::IUserManager>( + BindingOptions::new(), + Box::new(mock_provider), + ); di_container .get::<dyn subjects::IUserManager>()? @@ -420,7 +432,10 @@ mod tests di_container .binding_storage .borrow_mut() - .set::<dyn subjects::IUserManager>(Some("special"), Box::new(mock_provider)); + .set::<dyn subjects::IUserManager>( + BindingOptions::new().name("special"), + Box::new(mock_provider), + ); di_container .get_named::<dyn subjects::IUserManager>("special")? @@ -447,7 +462,7 @@ mod tests di_container .binding_storage .borrow_mut() - .set::<dyn subjects::INumber>(None, Box::new(mock_provider)); + .set::<dyn subjects::INumber>(BindingOptions::new(), Box::new(mock_provider)); let first_number_rc = di_container.get::<dyn subjects::INumber>()?.singleton()?; @@ -479,7 +494,10 @@ mod tests di_container .binding_storage .borrow_mut() - .set::<dyn subjects::INumber>(Some("cool"), Box::new(mock_provider)); + .set::<dyn subjects::INumber>( + BindingOptions::new().name("cool"), + Box::new(mock_provider), + ); let first_number_rc = di_container .get_named::<dyn subjects::INumber>("cool")? @@ -567,7 +585,7 @@ mod tests di_container .binding_storage .borrow_mut() - .set::<IUserManagerFactory>(None, Box::new(mock_provider)); + .set::<IUserManagerFactory>(BindingOptions::new(), Box::new(mock_provider)); di_container.get::<IUserManagerFactory>()?.factory()?; @@ -645,7 +663,10 @@ mod tests di_container .binding_storage .borrow_mut() - .set::<IUserManagerFactory>(Some("special"), Box::new(mock_provider)); + .set::<IUserManagerFactory>( + BindingOptions::new().name("special"), + Box::new(mock_provider), + ); di_container .get_named::<IUserManagerFactory>("special")? diff --git a/src/di_container/mod.rs b/src/di_container/mod.rs index 63733f5..7e8c11f 100644 --- a/src/di_container/mod.rs +++ b/src/di_container/mod.rs @@ -14,7 +14,7 @@ pub mod blocking; /// # /// BindingOptions::new().name("foo"); /// ``` -#[derive(Debug, Default, Clone)] +#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)] pub struct BindingOptions<'a> { name: Option<&'a str>, @@ -24,7 +24,7 @@ impl<'a> BindingOptions<'a> { /// Returns a new `BindingOptions`. #[must_use] - pub fn new() -> Self + pub const fn new() -> Self { Self { name: None } } |