aboutsummaryrefslogtreecommitdiff
path: root/src/di_container
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2023-09-17 13:32:06 +0200
committerHampusM <hampus@hampusmat.com>2023-09-17 13:32:06 +0200
commita1ddd1bc6e1af0d98b87126d3e86da30bc1d3f1c (patch)
treed4a9cfd9e3970a955e27ac518a593f55e8ad8d9c /src/di_container
parent3e3a853615e97ee7c3aef09736eae8170c6fd78e (diff)
refactor!: make the blocking DI container not inside a Rc
BREAKING CHANGE: The blocking DI container is no longer inside of a Rc. This affects BindingBuilder, BindingScopeConfigurator, BindingWhenConfigurator & Injectable
Diffstat (limited to 'src/di_container')
-rw-r--r--src/di_container/binding_storage.rs10
-rw-r--r--src/di_container/blocking/binding/builder.rs49
-rw-r--r--src/di_container/blocking/binding/scope_configurator.rs25
-rw-r--r--src/di_container/blocking/binding/when_configurator.rs13
-rw-r--r--src/di_container/blocking/mod.rs63
5 files changed, 82 insertions, 78 deletions
diff --git a/src/di_container/binding_storage.rs b/src/di_container/binding_storage.rs
index 2451791..b3fea6f 100644
--- a/src/di_container/binding_storage.rs
+++ b/src/di_container/binding_storage.rs
@@ -63,6 +63,16 @@ where
}
}
+impl<Provider> Default for DIContainerBindingStorage<Provider>
+where
+ Provider: 'static + ?Sized,
+{
+ fn default() -> Self
+ {
+ Self::new()
+ }
+}
+
#[derive(Debug, PartialEq, Eq, Hash)]
struct BindingId<'opts>
{
diff --git a/src/di_container/blocking/binding/builder.rs b/src/di_container/blocking/binding/builder.rs
index 64e787e..8eebcc0 100644
--- a/src/di_container/blocking/binding/builder.rs
+++ b/src/di_container/blocking/binding/builder.rs
@@ -1,7 +1,6 @@
//! Binding builder for types inside of a [`DIContainer`].
use std::any::type_name;
use std::marker::PhantomData;
-use std::rc::Rc;
use crate::di_container::blocking::binding::scope_configurator::BindingScopeConfigurator;
#[cfg(feature = "factory")]
@@ -16,22 +15,22 @@ use_double!(crate::di_container::blocking::DIContainer);
/// Binding builder for type `Interface` inside a [`DIContainer`].
#[must_use = "No binding will be created if you don't use the binding builder"]
-pub struct BindingBuilder<Interface>
+pub struct BindingBuilder<'di_container, Interface>
where
Interface: 'static + ?Sized,
{
- di_container: Rc<DIContainer>,
+ di_container: &'di_container DIContainer,
dependency_history_factory: fn() -> DependencyHistory,
interface_phantom: PhantomData<Interface>,
}
-impl<Interface> BindingBuilder<Interface>
+impl<'di_container, Interface> BindingBuilder<'di_container, Interface>
where
Interface: 'static + ?Sized,
{
pub(crate) fn new(
- di_container: Rc<DIContainer>,
+ di_container: &'di_container DIContainer,
dependency_history_factory: fn() -> DependencyHistory,
) -> Self
{
@@ -83,7 +82,10 @@ where
/// ```
pub fn to<Implementation>(
self,
- ) -> Result<BindingScopeConfigurator<Interface, Implementation>, BindingBuilderError>
+ ) -> Result<
+ BindingScopeConfigurator<'di_container, Interface, Implementation>,
+ BindingBuilderError,
+ >
where
Implementation: Injectable<DIContainer>,
{
@@ -97,7 +99,7 @@ where
}
let binding_scope_configurator = BindingScopeConfigurator::new(
- self.di_container.clone(),
+ self.di_container,
self.dependency_history_factory,
);
@@ -151,13 +153,13 @@ where
/// di_container
/// .bind::<ICustomerFactory>()
/// .to_factory(&|context| {
- /// Box::new(move |name, id| {
- /// let customer_id_factory = context
- /// .get::<ICustomerIDFactory>()
- /// .unwrap()
- /// .factory()
- /// .unwrap();
+ /// let customer_id_factory = context
+ /// .get::<ICustomerIDFactory>()
+ /// .unwrap()
+ /// .factory()
+ /// .unwrap();
///
+ /// Box::new(move |name, id| {
/// let customer_id = customer_id_factory(id);
///
/// let customer = TransientPtr::new(Customer::new(name, customer_id));
@@ -174,12 +176,12 @@ where
pub fn to_factory<Args, Return, Func>(
self,
factory_func: &'static Func,
- ) -> Result<BindingWhenConfigurator<Interface>, BindingBuilderError>
+ ) -> Result<BindingWhenConfigurator<'di_container, Interface>, BindingBuilderError>
where
Args: std::marker::Tuple + 'static,
Return: 'static + ?Sized,
Interface: Fn<Args, Output = crate::ptr::TransientPtr<Return>>,
- Func: Fn<(std::rc::Rc<DIContainer>,), Output = Box<Interface>>,
+ Func: Fn(&DIContainer) -> Box<Interface>,
{
use crate::private::castable_factory::blocking::CastableFactory;
@@ -260,14 +262,13 @@ where
pub fn to_default_factory<Return, FactoryFunc>(
self,
factory_func: &'static FactoryFunc,
- ) -> Result<BindingWhenConfigurator<Interface>, BindingBuilderError>
+ ) -> Result<BindingWhenConfigurator<'di_container, Interface>, BindingBuilderError>
where
Return: 'static + ?Sized,
- FactoryFunc: Fn<
- (Rc<DIContainer>,),
- Output = crate::ptr::TransientPtr<
- dyn Fn<(), Output = crate::ptr::TransientPtr<Return>>,
- >,
+ FactoryFunc: Fn(
+ &DIContainer,
+ ) -> crate::ptr::TransientPtr<
+ dyn Fn<(), Output = crate::ptr::TransientPtr<Return>>,
>,
{
use crate::private::castable_factory::blocking::CastableFactory;
@@ -325,7 +326,7 @@ mod tests
.once();
let binding_builder = BindingBuilder::<dyn subjects::INumber>::new(
- Rc::new(mock_di_container),
+ &mock_di_container,
MockDependencyHistory::new,
);
@@ -361,7 +362,7 @@ mod tests
.once();
let binding_builder = BindingBuilder::<IUserManagerFactory>::new(
- Rc::new(mock_di_container),
+ &mock_di_container,
MockDependencyHistory::new,
);
@@ -403,7 +404,7 @@ mod tests
.once();
let binding_builder = BindingBuilder::<dyn subjects::IUserManager>::new(
- Rc::new(mock_di_container),
+ &mock_di_container,
MockDependencyHistory::new,
);
diff --git a/src/di_container/blocking/binding/scope_configurator.rs b/src/di_container/blocking/binding/scope_configurator.rs
index be469ba..3d939ba 100644
--- a/src/di_container/blocking/binding/scope_configurator.rs
+++ b/src/di_container/blocking/binding/scope_configurator.rs
@@ -1,6 +1,5 @@
//! Scope configurator for a binding for types inside of a [`DIContainer`].
use std::marker::PhantomData;
-use std::rc::Rc;
use crate::di_container::blocking::binding::when_configurator::BindingWhenConfigurator;
use crate::di_container::BindingOptions;
@@ -14,25 +13,26 @@ use_double!(crate::dependency_history::DependencyHistory);
use_double!(crate::di_container::blocking::DIContainer);
/// Scope configurator for a binding for type `Interface` inside a [`DIContainer`].
-pub struct BindingScopeConfigurator<Interface, Implementation>
+pub struct BindingScopeConfigurator<'di_container, Interface, Implementation>
where
Interface: 'static + ?Sized,
Implementation: Injectable<DIContainer>,
{
- di_container: Rc<DIContainer>,
+ di_container: &'di_container DIContainer,
dependency_history_factory: fn() -> DependencyHistory,
interface_phantom: PhantomData<Interface>,
implementation_phantom: PhantomData<Implementation>,
}
-impl<Interface, Implementation> BindingScopeConfigurator<Interface, Implementation>
+impl<'di_container, Interface, Implementation>
+ BindingScopeConfigurator<'di_container, Interface, Implementation>
where
Interface: 'static + ?Sized,
Implementation: Injectable<DIContainer>,
{
pub(crate) fn new(
- di_container: Rc<DIContainer>,
+ di_container: &'di_container DIContainer,
dependency_history_factory: fn() -> DependencyHistory,
) -> Self
{
@@ -48,7 +48,7 @@ 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<'di_container, Interface>
{
self.set_in_transient_scope();
@@ -61,11 +61,14 @@ where
/// Will return Err if resolving the implementation fails.
pub fn in_singleton_scope(
self,
- ) -> Result<BindingWhenConfigurator<Interface>, BindingScopeConfiguratorError>
+ ) -> Result<
+ BindingWhenConfigurator<'di_container, Interface>,
+ BindingScopeConfiguratorError,
+ >
{
let singleton: SingletonPtr<Implementation> = SingletonPtr::from(
Implementation::resolve(
- &self.di_container,
+ self.di_container,
(self.dependency_history_factory)(),
)
.map_err(BindingScopeConfiguratorError::SingletonResolveFailed)?,
@@ -111,8 +114,7 @@ mod tests
dyn subjects::IUserManager,
subjects::UserManager,
>::new(
- Rc::new(di_container_mock),
- MockDependencyHistory::new,
+ &di_container_mock, MockDependencyHistory::new
);
binding_scope_configurator.in_transient_scope();
@@ -133,8 +135,7 @@ mod tests
dyn subjects::IUserManager,
subjects::UserManager,
>::new(
- Rc::new(di_container_mock),
- MockDependencyHistory::new,
+ &di_container_mock, MockDependencyHistory::new
);
assert!(binding_scope_configurator.in_singleton_scope().is_ok());
diff --git a/src/di_container/blocking/binding/when_configurator.rs b/src/di_container/blocking/binding/when_configurator.rs
index 3d267b2..2a1af2c 100644
--- a/src/di_container/blocking/binding/when_configurator.rs
+++ b/src/di_container/blocking/binding/when_configurator.rs
@@ -1,7 +1,6 @@
//! When configurator for a binding for types inside of a [`DIContainer`].
use std::any::type_name;
use std::marker::PhantomData;
-use std::rc::Rc;
use crate::di_container::BindingOptions;
use crate::errors::di_container::BindingWhenConfiguratorError;
@@ -10,20 +9,20 @@ use crate::util::use_double;
use_double!(crate::di_container::blocking::DIContainer);
/// When configurator for a binding for type `Interface` inside a [`DIContainer`].
-pub struct BindingWhenConfigurator<Interface>
+pub struct BindingWhenConfigurator<'di_container, Interface>
where
Interface: 'static + ?Sized,
{
- di_container: Rc<DIContainer>,
+ di_container: &'di_container DIContainer,
interface_phantom: PhantomData<Interface>,
}
-impl<Interface> BindingWhenConfigurator<Interface>
+impl<'di_container, Interface> BindingWhenConfigurator<'di_container, Interface>
where
Interface: 'static + ?Sized,
{
- pub(crate) fn new(di_container: Rc<DIContainer>) -> Self
+ pub(crate) fn new(di_container: &'di_container DIContainer) -> Self
{
Self {
di_container,
@@ -88,9 +87,7 @@ mod tests
.once();
let binding_when_configurator =
- BindingWhenConfigurator::<dyn subjects::INumber>::new(Rc::new(
- di_container_mock,
- ));
+ BindingWhenConfigurator::<dyn subjects::INumber>::new(&di_container_mock);
assert!(binding_when_configurator.when_named("cool").is_ok());
}
diff --git a/src/di_container/blocking/mod.rs b/src/di_container/blocking/mod.rs
index 09e7db1..a38b5da 100644
--- a/src/di_container/blocking/mod.rs
+++ b/src/di_container/blocking/mod.rs
@@ -51,7 +51,6 @@
//! ```
use std::any::type_name;
use std::cell::RefCell;
-use std::rc::Rc;
use crate::di_container::binding_storage::DIContainerBindingStorage;
use crate::di_container::blocking::binding::builder::BindingBuilder;
@@ -74,6 +73,7 @@ pub(crate) type BindingOptionsWithLt<'a> = BindingOptions<'a>;
pub(crate) type BindingOptionsWithLt = BindingOptions<'static>;
/// Blocking dependency injection container.
+#[derive(Default)]
pub struct DIContainer
{
binding_storage: RefCell<DIContainerBindingStorage<dyn IProvider<Self>>>,
@@ -83,11 +83,11 @@ impl DIContainer
{
/// Returns a new `DIContainer`.
#[must_use]
- pub fn new() -> Rc<Self>
+ pub fn new() -> Self
{
- Rc::new(Self {
+ Self {
binding_storage: RefCell::new(DIContainerBindingStorage::new()),
- })
+ }
}
}
@@ -96,7 +96,7 @@ impl DIContainer
{
/// Returns a new [`BindingBuilder`] for the given interface.
#[allow(clippy::missing_panics_doc)]
- pub fn bind<Interface>(self: &mut Rc<Self>) -> BindingBuilder<Interface>
+ pub fn bind<Interface>(&mut self) -> BindingBuilder<'_, Interface>
where
Interface: 'static + ?Sized,
{
@@ -104,7 +104,7 @@ impl DIContainer
panic!("Nope");
#[cfg(not(test))]
- BindingBuilder::new(self.clone(), DependencyHistory::new)
+ BindingBuilder::new(self, DependencyHistory::new)
}
/// Returns the type bound with `Interface`.
@@ -114,7 +114,7 @@ impl DIContainer
/// - 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>
+ pub fn get<Interface>(&self) -> Result<SomePtr<Interface>, DIContainerError>
where
Interface: 'static + ?Sized,
{
@@ -129,7 +129,7 @@ impl DIContainer
/// - Resolving the binding for `Interface` fails
/// - Casting the binding for `Interface` fails
pub fn get_named<Interface>(
- self: &Rc<Self>,
+ &self,
name: &'static str,
) -> Result<SomePtr<Interface>, DIContainerError>
where
@@ -177,7 +177,7 @@ impl DIContainer
/// # }
/// ```
pub fn get_bound<Interface>(
- self: &Rc<Self>,
+ &self,
dependency_history: DependencyHistory,
binding_options: BindingOptionsWithLt,
) -> Result<SomePtr<Interface>, DIContainerError>
@@ -215,7 +215,7 @@ impl DIContainer
binding_kind: "factory",
})?;
- Ok(SomePtr::Factory(factory.call(self.clone()).into()))
+ Ok(SomePtr::Factory(factory.call(self).into()))
}
#[cfg(feature = "factory")]
Providable::DefaultFactory(factory_binding) => {
@@ -234,15 +234,12 @@ impl DIContainer
binding_kind: "default factory",
})?;
- Ok(SomePtr::Transient(default_factory.call(self.clone())()))
+ Ok(SomePtr::Transient(default_factory.call(self)()))
}
}
}
- fn has_binding<Interface>(
- self: &Rc<Self>,
- binding_options: BindingOptionsWithLt,
- ) -> bool
+ fn has_binding<Interface>(&self, binding_options: BindingOptionsWithLt) -> bool
where
Interface: ?Sized + 'static,
{
@@ -252,7 +249,7 @@ impl DIContainer
}
fn set_binding<Interface>(
- self: &Rc<Self>,
+ &self,
binding_options: BindingOptions<'static>,
provider: Box<dyn IProvider<Self>>,
) where
@@ -264,7 +261,7 @@ impl DIContainer
}
fn remove_binding<Interface>(
- self: &Rc<Self>,
+ &self,
binding_options: BindingOptions<'static>,
) -> Option<Box<dyn IProvider<Self>>>
where
@@ -279,7 +276,7 @@ impl DIContainer
impl DIContainer
{
fn get_binding_providable<Interface>(
- self: &Rc<Self>,
+ &self,
binding_options: BindingOptionsWithLt,
dependency_history: DependencyHistory,
) -> Result<Providable<Self>, DIContainerError>
@@ -494,15 +491,14 @@ mod tests
let di_container = DIContainer::new();
- let factory_func: &dyn Fn(Rc<DIContainer>) -> Box<IUserManagerFactory> =
- &|_: Rc<DIContainer>| {
- Box::new(move |users| {
- let user_manager: TransientPtr<dyn IUserManager> =
- TransientPtr::new(UserManager::new(users));
+ let factory_func: &dyn Fn(&DIContainer) -> Box<IUserManagerFactory> = &|_| {
+ Box::new(move |users| {
+ let user_manager: TransientPtr<dyn IUserManager> =
+ TransientPtr::new(UserManager::new(users));
- user_manager
- })
- };
+ user_manager
+ })
+ };
let mut mock_provider = MockIProvider::new();
@@ -572,15 +568,14 @@ mod tests
let di_container = DIContainer::new();
- let factory_func: &dyn Fn(Rc<DIContainer>) -> Box<IUserManagerFactory> =
- &|_: Rc<DIContainer>| {
- Box::new(move |users| {
- let user_manager: TransientPtr<dyn IUserManager> =
- TransientPtr::new(UserManager::new(users));
+ let factory_func: &dyn Fn(&DIContainer) -> Box<IUserManagerFactory> = &|_| {
+ Box::new(move |users| {
+ let user_manager: TransientPtr<dyn IUserManager> =
+ TransientPtr::new(UserManager::new(users));
- user_manager
- })
- };
+ user_manager
+ })
+ };
let mut mock_provider = MockIProvider::new();