aboutsummaryrefslogtreecommitdiff
path: root/src/di_container/blocking
diff options
context:
space:
mode:
Diffstat (limited to 'src/di_container/blocking')
-rw-r--r--src/di_container/blocking/binding/builder.rs273
-rw-r--r--src/di_container/blocking/binding/scope_configurator.rs45
-rw-r--r--src/di_container/blocking/binding/when_configurator.rs46
-rw-r--r--src/di_container/blocking/mod.rs166
-rw-r--r--src/di_container/blocking/prelude.rs2
5 files changed, 306 insertions, 226 deletions
diff --git a/src/di_container/blocking/binding/builder.rs b/src/di_container/blocking/binding/builder.rs
index 8e15f0c..e1c1561 100644
--- a/src/di_container/blocking/binding/builder.rs
+++ b/src/di_container/blocking/binding/builder.rs
@@ -1,4 +1,6 @@
-//! Binding builder for types inside of a [`DIContainer`].
+//! Binding builder for types inside of a [`IDIContainer`].
+//!
+//! [`IDIContainer`]: crate::di_container::blocking::IDIContainer
use std::any::type_name;
use std::marker::PhantomData;
use std::rc::Rc;
@@ -6,24 +8,28 @@ use std::rc::Rc;
use crate::di_container::blocking::binding::scope_configurator::BindingScopeConfigurator;
#[cfg(feature = "factory")]
use crate::di_container::blocking::binding::when_configurator::BindingWhenConfigurator;
-use crate::di_container::blocking::DIContainer;
+use crate::di_container::blocking::IDIContainer;
use crate::errors::di_container::BindingBuilderError;
use crate::interfaces::injectable::Injectable;
-/// Binding builder for type `Interface` inside a [`DIContainer`].
-pub struct BindingBuilder<Interface>
+/// Binding builder for type `Interface` inside a [`IDIContainer`].
+///
+/// [`IDIContainer`]: crate::di_container::blocking::IDIContainer
+pub struct BindingBuilder<Interface, DIContainerType>
where
Interface: 'static + ?Sized,
+ DIContainerType: IDIContainer,
{
- di_container: Rc<DIContainer>,
+ di_container: Rc<DIContainerType>,
interface_phantom: PhantomData<Interface>,
}
-impl<Interface> BindingBuilder<Interface>
+impl<Interface, DIContainerType> BindingBuilder<Interface, DIContainerType>
where
Interface: 'static + ?Sized,
+ DIContainerType: IDIContainer,
{
- pub(crate) fn new(di_container: Rc<DIContainer>) -> Self
+ pub(crate) fn new(di_container: Rc<DIContainerType>) -> Self
{
Self {
di_container,
@@ -32,13 +38,13 @@ where
}
/// Creates a binding of type `Interface` to type `Implementation` inside of the
- /// associated [`DIContainer`].
+ /// associated [`IDIContainer`].
///
/// The scope of the binding is transient. But that can be changed by using the
/// returned [`BindingScopeConfigurator`]
///
/// # Errors
- /// Will return Err if the associated [`DIContainer`] already have a binding for
+ /// Will return Err if the associated [`IDIContainer`] already have a binding for
/// the interface.
///
/// # Examples
@@ -46,6 +52,7 @@ where
/// # use std::error::Error;
/// #
/// # use syrette::{DIContainer, injectable};
+ /// # use syrette::di_container::blocking::IDIContainer;
/// #
/// # trait Foo {}
/// #
@@ -70,16 +77,19 @@ where
/// # Ok(())
/// # }
/// ```
+ ///
+ /// [`IDIContainer`]: crate::di_container::blocking::IDIContainer
pub fn to<Implementation>(
&self,
- ) -> Result<BindingScopeConfigurator<Interface, Implementation>, BindingBuilderError>
+ ) -> Result<
+ BindingScopeConfigurator<Interface, Implementation, DIContainerType>,
+ BindingBuilderError,
+ >
where
- Implementation: Injectable,
+ Implementation: Injectable<DIContainerType>,
{
{
- let bindings = self.di_container.bindings.borrow();
-
- if bindings.has::<Interface>(None) {
+ if self.di_container.has_binding::<Interface>(None) {
return Err(BindingBuilderError::BindingAlreadyExists(type_name::<
Interface,
>(
@@ -96,10 +106,10 @@ where
}
/// Creates a binding of factory type `Interface` to a factory inside of the
- /// associated [`DIContainer`].
+ /// associated [`IDIContainer`].
///
/// # Errors
- /// Will return Err if the associated [`DIContainer`] already have a binding for
+ /// Will return Err if the associated [`IDIContainer`] already have a binding for
/// the interface.
///
/// # Examples
@@ -108,6 +118,7 @@ where
/// #
/// # use syrette::{DIContainer, factory};
/// # use syrette::ptr::TransientPtr;
+ /// # use syrette::di_container::blocking::IDIContainer;
/// #
/// # trait ICustomerID {}
/// # trait ICustomer {}
@@ -158,36 +169,31 @@ where
/// # Ok(())
/// # }
/// ```
+ ///
+ /// [`IDIContainer`]: crate::di_container::blocking::IDIContainer
#[cfg(feature = "factory")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))]
pub fn to_factory<Args, Return, Func>(
&self,
factory_func: &'static Func,
- ) -> Result<BindingWhenConfigurator<Interface>, BindingBuilderError>
+ ) -> Result<BindingWhenConfigurator<Interface, DIContainerType>, BindingBuilderError>
where
Args: 'static,
Return: 'static + ?Sized,
Interface: Fn<Args, Output = crate::ptr::TransientPtr<Return>>,
- Func: Fn<(std::rc::Rc<DIContainer>,), Output = Box<Interface>>,
+ Func: Fn<(std::rc::Rc<DIContainerType>,), Output = Box<Interface>>,
{
use crate::castable_factory::blocking::CastableFactory;
- {
- let bindings = self.di_container.bindings.borrow();
-
- if bindings.has::<Interface>(None) {
- return Err(BindingBuilderError::BindingAlreadyExists(type_name::<
- Interface,
- >(
- )));
- }
+ if self.di_container.has_binding::<Interface>(None) {
+ return Err(BindingBuilderError::BindingAlreadyExists(type_name::<
+ Interface,
+ >()));
}
- let mut bindings_mut = self.di_container.bindings.borrow_mut();
-
let factory_impl = CastableFactory::new(factory_func);
- bindings_mut.set::<Interface>(
+ self.di_container.set_binding::<Interface>(
None,
Box::new(crate::provider::blocking::FactoryProvider::new(
crate::ptr::FactoryPtr::new(factory_impl),
@@ -199,10 +205,10 @@ where
}
/// Creates a binding of type `Interface` to a factory that takes no arguments
- /// inside of the associated [`DIContainer`].
+ /// inside of the associated [`IDIContainer`].
///
/// # Errors
- /// Will return Err if the associated [`DIContainer`] already have a binding for
+ /// Will return Err if the associated [`IDIContainer`] already have a binding for
/// the interface.
///
/// # Examples
@@ -211,6 +217,7 @@ where
/// #
/// # use syrette::{DIContainer, factory};
/// # use syrette::ptr::TransientPtr;
+ /// # use syrette::di_container::blocking::IDIContainer;
/// #
/// # trait IBuffer {}
/// #
@@ -248,16 +255,18 @@ where
/// # Ok(())
/// # }
/// ```
+ ///
+ /// [`IDIContainer`]: crate::di_container::blocking::IDIContainer
#[cfg(feature = "factory")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))]
pub fn to_default_factory<Return, FactoryFunc>(
&self,
factory_func: &'static FactoryFunc,
- ) -> Result<BindingWhenConfigurator<Interface>, BindingBuilderError>
+ ) -> Result<BindingWhenConfigurator<Interface, DIContainerType>, BindingBuilderError>
where
Return: 'static + ?Sized,
FactoryFunc: Fn<
- (Rc<DIContainer>,),
+ (Rc<DIContainerType>,),
Output = crate::ptr::TransientPtr<
dyn Fn<(), Output = crate::ptr::TransientPtr<Return>>,
>,
@@ -265,22 +274,15 @@ where
{
use crate::castable_factory::blocking::CastableFactory;
- {
- let bindings = self.di_container.bindings.borrow();
-
- if bindings.has::<Interface>(None) {
- return Err(BindingBuilderError::BindingAlreadyExists(type_name::<
- Interface,
- >(
- )));
- }
+ if self.di_container.has_binding::<Interface>(None) {
+ return Err(BindingBuilderError::BindingAlreadyExists(type_name::<
+ Interface,
+ >()));
}
- let mut bindings_mut = self.di_container.bindings.borrow_mut();
-
let factory_impl = CastableFactory::new(factory_func);
- bindings_mut.set::<Interface>(
+ self.di_container.set_binding::<Interface>(
None,
Box::new(crate::provider::blocking::FactoryProvider::new(
crate::ptr::FactoryPtr::new(factory_impl),
@@ -297,92 +299,34 @@ mod tests
{
use std::error::Error;
+ use mockall::predicate::eq;
+
use super::*;
- use crate::ptr::TransientPtr;
- use crate::test_utils::subjects;
+ use crate::test_utils::{mocks, subjects};
#[test]
fn can_bind_to() -> Result<(), Box<dyn Error>>
{
- let mut di_container = DIContainer::new();
+ let mut mock_di_container = mocks::blocking_di_container::MockDIContainer::new();
- assert_eq!(di_container.bindings.borrow().count(), 0);
+ mock_di_container
+ .expect_has_binding::<dyn subjects::INumber>()
+ .with(eq(None))
+ .return_once(|_name| false)
+ .once();
- di_container
- .bind::<dyn subjects::IUserManager>()
- .to::<subjects::UserManager>()?;
+ mock_di_container
+ .expect_set_binding::<dyn subjects::INumber>()
+ .withf(|name, _provider| name.is_none())
+ .return_once(|_name, _provider| ())
+ .once();
- assert_eq!(di_container.bindings.borrow().count(), 1);
+ let binding_builder = BindingBuilder::<
+ dyn subjects::INumber,
+ mocks::blocking_di_container::MockDIContainer,
+ >::new(Rc::new(mock_di_container));
- Ok(())
- }
-
- #[test]
- fn can_bind_to_transient() -> Result<(), Box<dyn Error>>
- {
- let mut di_container = DIContainer::new();
-
- assert_eq!(di_container.bindings.borrow().count(), 0);
-
- di_container
- .bind::<dyn subjects::IUserManager>()
- .to::<subjects::UserManager>()?
- .in_transient_scope();
-
- assert_eq!(di_container.bindings.borrow().count(), 1);
-
- Ok(())
- }
-
- #[test]
- fn can_bind_to_transient_when_named() -> Result<(), Box<dyn Error>>
- {
- let mut di_container = DIContainer::new();
-
- assert_eq!(di_container.bindings.borrow().count(), 0);
-
- di_container
- .bind::<dyn subjects::IUserManager>()
- .to::<subjects::UserManager>()?
- .in_transient_scope()
- .when_named("regular")?;
-
- assert_eq!(di_container.bindings.borrow().count(), 1);
-
- Ok(())
- }
-
- #[test]
- fn can_bind_to_singleton() -> Result<(), Box<dyn Error>>
- {
- let mut di_container = DIContainer::new();
-
- assert_eq!(di_container.bindings.borrow().count(), 0);
-
- di_container
- .bind::<dyn subjects::IUserManager>()
- .to::<subjects::UserManager>()?
- .in_singleton_scope()?;
-
- assert_eq!(di_container.bindings.borrow().count(), 1);
-
- Ok(())
- }
-
- #[test]
- fn can_bind_to_singleton_when_named() -> Result<(), Box<dyn Error>>
- {
- let mut di_container = DIContainer::new();
-
- assert_eq!(di_container.bindings.borrow().count(), 0);
-
- di_container
- .bind::<dyn subjects::IUserManager>()
- .to::<subjects::UserManager>()?
- .in_singleton_scope()?
- .when_named("cool")?;
-
- assert_eq!(di_container.bindings.borrow().count(), 1);
+ binding_builder.to::<subjects::Number>()?;
Ok(())
}
@@ -393,57 +337,80 @@ mod tests
{
use crate as syrette;
use crate::factory;
+ use crate::ptr::TransientPtr;
#[factory]
- type IUserManagerFactory = dyn Fn() -> dyn subjects::IUserManager;
+ type IUserManagerFactory = dyn Fn(i32, String) -> dyn subjects::IUserManager;
- let mut di_container = DIContainer::new();
+ let mut mock_di_container = mocks::blocking_di_container::MockDIContainer::new();
- assert_eq!(di_container.bindings.borrow().count(), 0);
+ mock_di_container
+ .expect_has_binding::<IUserManagerFactory>()
+ .with(eq(None))
+ .return_once(|_name| false)
+ .once();
- di_container
- .bind::<IUserManagerFactory>()
- .to_factory(&|_| {
- Box::new(move || {
- let user_manager: TransientPtr<dyn subjects::IUserManager> =
- TransientPtr::new(subjects::UserManager::new());
+ mock_di_container
+ .expect_set_binding::<IUserManagerFactory>()
+ .withf(|name, _provider| name.is_none())
+ .return_once(|_name, _provider| ())
+ .once();
- user_manager
- })
- })?;
+ let binding_builder = BindingBuilder::<
+ IUserManagerFactory,
+ mocks::blocking_di_container::MockDIContainer,
+ >::new(Rc::new(mock_di_container));
- assert_eq!(di_container.bindings.borrow().count(), 1);
+ binding_builder.to_factory(&|_| {
+ Box::new(move |_num, _text| {
+ let user_manager: TransientPtr<dyn subjects::IUserManager> =
+ TransientPtr::new(subjects::UserManager::new());
+
+ user_manager
+ })
+ })?;
Ok(())
}
#[test]
#[cfg(feature = "factory")]
- fn can_bind_to_factory_when_named() -> Result<(), Box<dyn Error>>
+ fn can_bind_to_default_factory() -> Result<(), Box<dyn Error>>
{
+ use syrette_macros::declare_default_factory;
+
use crate as syrette;
- use crate::factory;
+ use crate::ptr::TransientPtr;
- #[factory]
- type IUserManagerFactory = dyn Fn() -> dyn subjects::IUserManager;
+ declare_default_factory!(dyn subjects::IUserManager);
+
+ let mut mock_di_container = mocks::blocking_di_container::MockDIContainer::new();
- let mut di_container = DIContainer::new();
+ mock_di_container
+ .expect_has_binding::<dyn subjects::IUserManager>()
+ .with(eq(None))
+ .return_once(|_name| false)
+ .once();
- assert_eq!(di_container.bindings.borrow().count(), 0);
+ mock_di_container
+ .expect_set_binding::<dyn subjects::IUserManager>()
+ .withf(|name, _provider| name.is_none())
+ .return_once(|_name, _provider| ())
+ .once();
- di_container
- .bind::<IUserManagerFactory>()
- .to_factory(&|_| {
- Box::new(move || {
- let user_manager: TransientPtr<dyn subjects::IUserManager> =
- TransientPtr::new(subjects::UserManager::new());
+ let binding_builder = BindingBuilder::<
+ dyn subjects::IUserManager,
+ mocks::blocking_di_container::MockDIContainer,
+ >::new(Rc::new(mock_di_container));
- user_manager
- })
- })?
- .when_named("awesome")?;
+ binding_builder.to_default_factory(&|_| {
+ Box::new(move || {
+ let user_manager: TransientPtr<dyn subjects::IUserManager> =
+ TransientPtr::new(subjects::UserManager::new());
- assert_eq!(di_container.bindings.borrow().count(), 1);
+ user_manager
+ })
+ })?;
Ok(())
}
diff --git a/src/di_container/blocking/binding/scope_configurator.rs b/src/di_container/blocking/binding/scope_configurator.rs
index 09897b6..5553415 100644
--- a/src/di_container/blocking/binding/scope_configurator.rs
+++ b/src/di_container/blocking/binding/scope_configurator.rs
@@ -1,31 +1,38 @@
-//! Scope configurator for a binding for types inside of a [`DIContainer`].
+//! Scope configurator for a binding for types inside of a [`IDIContainer`].
+//!
+//! [`IDIContainer`]: crate::di_container::blocking::IDIContainer
use std::marker::PhantomData;
use std::rc::Rc;
use crate::di_container::blocking::binding::when_configurator::BindingWhenConfigurator;
-use crate::di_container::blocking::DIContainer;
+use crate::di_container::blocking::IDIContainer;
use crate::errors::di_container::BindingScopeConfiguratorError;
use crate::interfaces::injectable::Injectable;
use crate::provider::blocking::{SingletonProvider, TransientTypeProvider};
use crate::ptr::SingletonPtr;
-/// Scope configurator for a binding for type 'Interface' inside a [`DIContainer`].
-pub struct BindingScopeConfigurator<Interface, Implementation>
+/// Scope configurator for a binding for type 'Interface' inside a [`IDIContainer`].
+///
+/// [`IDIContainer`]: crate::di_container::blocking::IDIContainer
+pub struct BindingScopeConfigurator<Interface, Implementation, DIContainerType>
where
Interface: 'static + ?Sized,
- Implementation: Injectable,
+ Implementation: Injectable<DIContainerType>,
+ DIContainerType: IDIContainer,
{
- di_container: Rc<DIContainer>,
+ di_container: Rc<DIContainerType>,
interface_phantom: PhantomData<Interface>,
implementation_phantom: PhantomData<Implementation>,
}
-impl<Interface, Implementation> BindingScopeConfigurator<Interface, Implementation>
+impl<Interface, Implementation, DIContainerType>
+ BindingScopeConfigurator<Interface, Implementation, DIContainerType>
where
Interface: 'static + ?Sized,
- Implementation: Injectable,
+ Implementation: Injectable<DIContainerType>,
+ DIContainerType: IDIContainer,
{
- pub(crate) fn new(di_container: Rc<DIContainer>) -> Self
+ pub(crate) fn new(di_container: Rc<DIContainerType>) -> Self
{
Self {
di_container,
@@ -38,13 +45,13 @@ where
///
/// This is the default.
#[allow(clippy::must_use_candidate)]
- pub fn in_transient_scope(&self) -> BindingWhenConfigurator<Interface>
+ pub fn in_transient_scope(
+ &self,
+ ) -> BindingWhenConfigurator<Interface, DIContainerType>
{
- let mut bindings_mut = self.di_container.bindings.borrow_mut();
-
- bindings_mut.set::<Interface>(
+ self.di_container.set_binding::<Interface>(
None,
- Box::new(TransientTypeProvider::<Implementation>::new()),
+ Box::new(TransientTypeProvider::<Implementation, DIContainerType>::new()),
);
BindingWhenConfigurator::new(self.di_container.clone())
@@ -56,16 +63,18 @@ where
/// Will return Err if resolving the implementation fails.
pub fn in_singleton_scope(
&self,
- ) -> Result<BindingWhenConfigurator<Interface>, BindingScopeConfiguratorError>
+ ) -> Result<
+ BindingWhenConfigurator<Interface, DIContainerType>,
+ BindingScopeConfiguratorError,
+ >
{
let singleton: SingletonPtr<Implementation> = SingletonPtr::from(
Implementation::resolve(&self.di_container, Vec::new())
.map_err(BindingScopeConfiguratorError::SingletonResolveFailed)?,
);
- let mut bindings_mut = self.di_container.bindings.borrow_mut();
-
- bindings_mut.set::<Interface>(None, Box::new(SingletonProvider::new(singleton)));
+ self.di_container
+ .set_binding::<Interface>(None, Box::new(SingletonProvider::new(singleton)));
Ok(BindingWhenConfigurator::new(self.di_container.clone()))
}
diff --git a/src/di_container/blocking/binding/when_configurator.rs b/src/di_container/blocking/binding/when_configurator.rs
index 9cd9bb6..5b9a8c0 100644
--- a/src/di_container/blocking/binding/when_configurator.rs
+++ b/src/di_container/blocking/binding/when_configurator.rs
@@ -1,25 +1,31 @@
-//! When configurator for a binding for types inside of a [`DIContainer`].
+//! When configurator for a binding for types inside of a [`IDIContainer`].
+//!
+//! [`IDIContainer`]: crate::di_container::blocking::IDIContainer
use std::any::type_name;
use std::marker::PhantomData;
use std::rc::Rc;
-use crate::di_container::blocking::DIContainer;
+use crate::di_container::blocking::IDIContainer;
use crate::errors::di_container::BindingWhenConfiguratorError;
-/// When configurator for a binding for type 'Interface' inside a [`DIContainer`].
-pub struct BindingWhenConfigurator<Interface>
+/// When configurator for a binding for type 'Interface' inside a [`IDIContainer`].
+///
+/// [`IDIContainer`]: crate::di_container::blocking::IDIContainer
+pub struct BindingWhenConfigurator<Interface, DIContainerType>
where
Interface: 'static + ?Sized,
+ DIContainerType: IDIContainer,
{
- di_container: Rc<DIContainer>,
+ di_container: Rc<DIContainerType>,
interface_phantom: PhantomData<Interface>,
}
-impl<Interface> BindingWhenConfigurator<Interface>
+impl<Interface, DIContainerType> BindingWhenConfigurator<Interface, DIContainerType>
where
Interface: 'static + ?Sized,
+ DIContainerType: IDIContainer,
{
- pub(crate) fn new(di_container: Rc<DIContainer>) -> Self
+ pub(crate) fn new(di_container: Rc<DIContainerType>) -> Self
{
Self {
di_container,
@@ -36,19 +42,21 @@ where
name: &'static str,
) -> Result<(), BindingWhenConfiguratorError>
{
- let mut bindings_mut = self.di_container.bindings.borrow_mut();
+ let binding = self
+ .di_container
+ .remove_binding::<Interface>(None)
+ .map_or_else(
+ || {
+ Err(BindingWhenConfiguratorError::BindingNotFound(type_name::<
+ Interface,
+ >(
+ )))
+ },
+ Ok,
+ )?;
- let binding = bindings_mut.remove::<Interface>(None).map_or_else(
- || {
- Err(BindingWhenConfiguratorError::BindingNotFound(type_name::<
- Interface,
- >(
- )))
- },
- Ok,
- )?;
-
- bindings_mut.set::<Interface>(Some(name), binding);
+ self.di_container
+ .set_binding::<Interface>(Some(name), binding);
Ok(())
}
diff --git a/src/di_container/blocking/mod.rs b/src/di_container/blocking/mod.rs
index f6b64fa..3b9c16e 100644
--- a/src/di_container/blocking/mod.rs
+++ b/src/di_container/blocking/mod.rs
@@ -5,6 +5,7 @@
//! use std::collections::HashMap;
//! use std::error::Error;
//!
+//! use syrette::di_container::blocking::IDIContainer;
//! use syrette::{injectable, DIContainer};
//!
//! trait IDatabaseService
@@ -61,11 +62,55 @@ use crate::provider::blocking::{IProvider, Providable};
use crate::ptr::SomePtr;
pub mod binding;
+pub mod prelude;
-/// Dependency injection container.
+/// Blocking dependency injection container interface.
+pub trait IDIContainer: Sized + 'static + details::DIContainerInternals
+{
+ /// Returns a new [`BindingBuilder`] for the given interface.
+ fn bind<Interface>(self: &mut Rc<Self>) -> BindingBuilder<Interface, Self>
+ where
+ Interface: 'static + ?Sized;
+
+ /// Returns the type bound with `Interface`.
+ ///
+ /// # Errors
+ /// Will return `Err` if:
+ /// - No binding for `Interface` exists
+ /// - Resolving the binding for `Interface` fails
+ /// - Casting the binding for `Interface` fails
+ fn get<Interface>(self: &Rc<Self>) -> Result<SomePtr<Interface>, DIContainerError>
+ where
+ Interface: 'static + ?Sized;
+
+ /// Returns the type bound with `Interface` and the specified name.
+ ///
+ /// # Errors
+ /// Will return `Err` if:
+ /// - No binding for `Interface` with name `name` exists
+ /// - Resolving the binding for `Interface` fails
+ /// - Casting the binding for `Interface` fails
+ fn get_named<Interface>(
+ self: &Rc<Self>,
+ name: &'static str,
+ ) -> Result<SomePtr<Interface>, DIContainerError>
+ where
+ Interface: 'static + ?Sized;
+
+ #[doc(hidden)]
+ fn get_bound<Interface>(
+ self: &Rc<Self>,
+ dependency_history: Vec<&'static str>,
+ name: Option<&'static str>,
+ ) -> Result<SomePtr<Interface>, DIContainerError>
+ where
+ Interface: 'static + ?Sized;
+}
+
+/// Blocking dependency injection container.
pub struct DIContainer
{
- bindings: RefCell<DIContainerBindingMap<dyn IProvider>>,
+ bindings: RefCell<DIContainerBindingMap<dyn IProvider<Self>>>,
}
impl DIContainer
@@ -78,38 +123,26 @@ impl DIContainer
bindings: RefCell::new(DIContainerBindingMap::new()),
})
}
+}
- /// Returns a new [`BindingBuilder`] for the given interface.
+impl IDIContainer for DIContainer
+{
#[must_use]
- pub fn bind<Interface>(self: &mut Rc<Self>) -> BindingBuilder<Interface>
+ fn bind<Interface>(self: &mut Rc<Self>) -> BindingBuilder<Interface, Self>
where
Interface: 'static + ?Sized,
{
- BindingBuilder::<Interface>::new(self.clone())
+ BindingBuilder::<Interface, Self>::new(self.clone())
}
- /// Returns the type bound with `Interface`.
- ///
- /// # Errors
- /// Will return `Err` if:
- /// - No binding for `Interface` exists
- /// - Resolving the binding for `Interface` fails
- /// - Casting the binding for `Interface` fails
- pub fn get<Interface>(self: &Rc<Self>) -> Result<SomePtr<Interface>, DIContainerError>
+ fn get<Interface>(self: &Rc<Self>) -> Result<SomePtr<Interface>, DIContainerError>
where
Interface: 'static + ?Sized,
{
self.get_bound::<Interface>(Vec::new(), None)
}
- /// Returns the type bound with `Interface` and the specified name.
- ///
- /// # Errors
- /// Will return `Err` if:
- /// - No binding for `Interface` with name `name` exists
- /// - Resolving the binding for `Interface` fails
- /// - Casting the binding for `Interface` fails
- pub fn get_named<Interface>(
+ fn get_named<Interface>(
self: &Rc<Self>,
name: &'static str,
) -> Result<SomePtr<Interface>, DIContainerError>
@@ -120,7 +153,7 @@ impl DIContainer
}
#[doc(hidden)]
- pub fn get_bound<Interface>(
+ fn get_bound<Interface>(
self: &Rc<Self>,
dependency_history: Vec<&'static str>,
name: Option<&'static str>,
@@ -133,10 +166,43 @@ impl DIContainer
self.handle_binding_providable(binding_providable)
}
+}
+
+impl details::DIContainerInternals for DIContainer
+{
+ fn has_binding<Interface>(self: &Rc<Self>, name: Option<&'static str>) -> bool
+ where
+ Interface: ?Sized + 'static,
+ {
+ self.bindings.borrow().has::<Interface>(name)
+ }
+
+ fn set_binding<Interface>(
+ self: &Rc<Self>,
+ name: Option<&'static str>,
+ provider: Box<dyn IProvider<Self>>,
+ ) where
+ Interface: 'static + ?Sized,
+ {
+ self.bindings.borrow_mut().set::<Interface>(name, provider);
+ }
+
+ fn remove_binding<Interface>(
+ self: &Rc<Self>,
+ name: Option<&'static str>,
+ ) -> Option<Box<dyn IProvider<Self>>>
+ where
+ Interface: 'static + ?Sized,
+ {
+ self.bindings.borrow_mut().remove::<Interface>(name)
+ }
+}
+impl DIContainer
+{
fn handle_binding_providable<Interface>(
self: &Rc<Self>,
- binding_providable: Providable,
+ binding_providable: Providable<Self>,
) -> Result<SomePtr<Interface>, DIContainerError>
where
Interface: 'static + ?Sized,
@@ -195,7 +261,7 @@ impl DIContainer
self: &Rc<Self>,
name: Option<&'static str>,
dependency_history: Vec<&'static str>,
- ) -> Result<Providable, DIContainerError>
+ ) -> Result<Providable<Self>, DIContainerError>
where
Interface: 'static + ?Sized,
{
@@ -219,6 +285,34 @@ impl DIContainer
}
}
+pub(crate) mod details
+{
+ use std::rc::Rc;
+
+ use crate::provider::blocking::IProvider;
+
+ pub trait DIContainerInternals
+ {
+ fn has_binding<Interface>(self: &Rc<Self>, name: Option<&'static str>) -> bool
+ where
+ Interface: ?Sized + 'static;
+
+ fn set_binding<Interface>(
+ self: &Rc<Self>,
+ name: Option<&'static str>,
+ provider: Box<dyn IProvider<Self>>,
+ ) where
+ Interface: 'static + ?Sized;
+
+ fn remove_binding<Interface>(
+ self: &Rc<Self>,
+ name: Option<&'static str>,
+ ) -> Option<Box<dyn IProvider<Self>>>
+ where
+ Interface: 'static + ?Sized;
+ }
+}
+
#[cfg(test)]
mod tests
{
@@ -238,13 +332,13 @@ mod tests
mock! {
Provider {}
- impl IProvider for Provider
+ impl IProvider<DIContainer> for Provider
{
fn provide(
&self,
di_container: &Rc<DIContainer>,
dependency_history: Vec<&'static str>,
- ) -> Result<Providable, InjectableError>;
+ ) -> Result<Providable<DIContainer>, InjectableError>;
}
}
@@ -276,13 +370,13 @@ mod tests
mock! {
Provider {}
- impl IProvider for Provider
+ impl IProvider<DIContainer> for Provider
{
fn provide(
&self,
di_container: &Rc<DIContainer>,
dependency_history: Vec<&'static str>,
- ) -> Result<Providable, InjectableError>;
+ ) -> Result<Providable<DIContainer>, InjectableError>;
}
}
@@ -314,13 +408,13 @@ mod tests
mock! {
Provider {}
- impl IProvider for Provider
+ impl IProvider<DIContainer> for Provider
{
fn provide(
&self,
di_container: &Rc<DIContainer>,
dependency_history: Vec<&'static str>,
- ) -> Result<Providable, InjectableError>;
+ ) -> Result<Providable<DIContainer>, InjectableError>;
}
}
@@ -359,13 +453,13 @@ mod tests
mock! {
Provider {}
- impl IProvider for Provider
+ impl IProvider<DIContainer> for Provider
{
fn provide(
&self,
di_container: &Rc<DIContainer>,
dependency_history: Vec<&'static str>,
- ) -> Result<Providable, InjectableError>;
+ ) -> Result<Providable<DIContainer>, InjectableError>;
}
}
@@ -459,13 +553,13 @@ mod tests
mock! {
Provider {}
- impl IProvider for Provider
+ impl IProvider<DIContainer> for Provider
{
fn provide(
&self,
di_container: &Rc<DIContainer>,
dependency_history: Vec<&'static str>,
- ) -> Result<Providable, InjectableError>;
+ ) -> Result<Providable<DIContainer>, InjectableError>;
}
}
@@ -556,13 +650,13 @@ mod tests
mock! {
Provider {}
- impl IProvider for Provider
+ impl IProvider<DIContainer> for Provider
{
fn provide(
&self,
di_container: &Rc<DIContainer>,
dependency_history: Vec<&'static str>,
- ) -> Result<Providable, InjectableError>;
+ ) -> Result<Providable<DIContainer>, InjectableError>;
}
}
diff --git a/src/di_container/blocking/prelude.rs b/src/di_container/blocking/prelude.rs
new file mode 100644
index 0000000..82db5e3
--- /dev/null
+++ b/src/di_container/blocking/prelude.rs
@@ -0,0 +1,2 @@
+//! Commonly used types.
+pub use crate::di_container::blocking::{DIContainer, IDIContainer};