From 5b0c6a52022e67a2d9cee251b3d08b9cb2b5f6cb Mon Sep 17 00:00:00 2001 From: HampusM Date: Sun, 9 Oct 2022 12:05:24 +0200 Subject: refactor!: reorganize DI containers BREAKING CHANGE: DIContainer, AsyncDIContainer & the binding structs have been relocated --- .../blocking/binding/scope_configurator.rs | 72 ++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/di_container/blocking/binding/scope_configurator.rs (limited to 'src/di_container/blocking/binding/scope_configurator.rs') diff --git a/src/di_container/blocking/binding/scope_configurator.rs b/src/di_container/blocking/binding/scope_configurator.rs new file mode 100644 index 0000000..09897b6 --- /dev/null +++ b/src/di_container/blocking/binding/scope_configurator.rs @@ -0,0 +1,72 @@ +//! 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::blocking::DIContainer; +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 +where + Interface: 'static + ?Sized, + Implementation: Injectable, +{ + di_container: Rc, + interface_phantom: PhantomData, + implementation_phantom: PhantomData, +} + +impl BindingScopeConfigurator +where + Interface: 'static + ?Sized, + Implementation: Injectable, +{ + pub(crate) fn new(di_container: Rc) -> Self + { + Self { + di_container, + interface_phantom: PhantomData, + implementation_phantom: PhantomData, + } + } + + /// Configures the binding to be in a transient scope. + /// + /// This is the default. + #[allow(clippy::must_use_candidate)] + pub fn in_transient_scope(&self) -> BindingWhenConfigurator + { + let mut bindings_mut = self.di_container.bindings.borrow_mut(); + + bindings_mut.set::( + None, + Box::new(TransientTypeProvider::::new()), + ); + + BindingWhenConfigurator::new(self.di_container.clone()) + } + + /// Configures the binding to be in a singleton scope. + /// + /// # Errors + /// Will return Err if resolving the implementation fails. + pub fn in_singleton_scope( + &self, + ) -> Result, BindingScopeConfiguratorError> + { + let singleton: SingletonPtr = 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::(None, Box::new(SingletonProvider::new(singleton))); + + Ok(BindingWhenConfigurator::new(self.di_container.clone())) + } +} -- cgit v1.2.3-18-g5258