aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2023-08-31 19:19:06 +0200
committerHampusM <hampus@hampusmat.com>2023-08-31 19:19:06 +0200
commit7bed48c852a741df5a14359916faf21d90d39814 (patch)
tree5cc94835225d356ed658cf78a99deeb1b4e730f8
parent0b4232d343e2214ead8fa62583bff2e948173ddf (diff)
refactor: pass around BindingOptions instead of name
-rw-r--r--src/di_container/asynchronous/binding/builder.rs59
-rw-r--r--src/di_container/asynchronous/binding/scope_configurator.rs9
-rw-r--r--src/di_container/asynchronous/binding/when_configurator.rs9
-rw-r--r--src/di_container/asynchronous/mod.rs63
-rw-r--r--src/di_container/binding_storage.rs170
-rw-r--r--src/di_container/blocking/binding/builder.rs44
-rw-r--r--src/di_container/blocking/binding/scope_configurator.rs13
-rw-r--r--src/di_container/blocking/binding/when_configurator.rs9
-rw-r--r--src/di_container/blocking/mod.rs63
-rw-r--r--src/di_container/mod.rs4
-rw-r--r--src/test_utils.rs16
11 files changed, 257 insertions, 202 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 }
}
diff --git a/src/test_utils.rs b/src/test_utils.rs
index 1e0e04d..a304a71 100644
--- a/src/test_utils.rs
+++ b/src/test_utils.rs
@@ -289,6 +289,7 @@ pub mod mocks
use crate::di_container::blocking::binding::builder::BindingBuilder;
use crate::di_container::blocking::details::DIContainerInternals;
use crate::di_container::blocking::{BindingOptionsWithLt, IDIContainer};
+ use crate::di_container::BindingOptions;
use crate::errors::di_container::DIContainerError;
use crate::provider::blocking::IProvider;
use crate::ptr::SomePtr;
@@ -328,21 +329,24 @@ pub mod mocks
impl DIContainerInternals for DIContainer
{
- 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;
#[doc(hidden)]
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;
@@ -406,21 +410,21 @@ pub mod mocks
{
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;