diff options
| author | HampusM <hampus@hampusmat.com> | 2023-08-31 19:19:06 +0200 | 
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2023-08-31 19:19:06 +0200 | 
| commit | 7bed48c852a741df5a14359916faf21d90d39814 (patch) | |
| tree | 5cc94835225d356ed658cf78a99deeb1b4e730f8 /src/di_container | |
| parent | 0b4232d343e2214ead8fa62583bff2e948173ddf (diff) | |
refactor: pass around BindingOptions instead of name
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 }      } | 
