aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2022-09-12 20:22:13 +0200
committerHampusM <hampus@hampusmat.com>2022-09-17 14:33:15 +0200
commitc1e682c25c24be3174d44ceb95b0537c38299d0c (patch)
tree6e59f37e1b98e68fad2e3e2fe4a428ac97fcf8b4
parente8e48906a3899e71c9c9d86a3d4528cb7d17e5b9 (diff)
feat!: allow factories access to DI container
BREAKING CHANGE: Factory types should now be written with the Fn trait instead of the IFactory trait and the to_factory & to_default_factory methods of BindingBuilder now expect a function returning a factory function
-rw-r--r--examples/basic/bootstrap.rs3
-rw-r--r--examples/factory/bootstrap.rs11
-rw-r--r--examples/factory/interfaces/user.rs4
-rw-r--r--examples/generics/bootstrap.rs3
-rw-r--r--examples/unbound/bootstrap.rs3
-rw-r--r--examples/with-3rd-party/bootstrap.rs5
-rw-r--r--macros/src/factory_type_alias.rs75
-rw-r--r--macros/src/fn_trait.rs68
-rw-r--r--macros/src/lib.rs26
-rw-r--r--src/di_container.rs173
-rw-r--r--src/provider/blocking.rs17
11 files changed, 233 insertions, 155 deletions
diff --git a/examples/basic/bootstrap.rs b/examples/basic/bootstrap.rs
index 30f6df3..2c45676 100644
--- a/examples/basic/bootstrap.rs
+++ b/examples/basic/bootstrap.rs
@@ -3,12 +3,9 @@ use std::rc::Rc;
use syrette::DIContainer;
-// Concrete implementations
use crate::animals::cat::Cat;
use crate::animals::dog::Dog;
use crate::animals::human::Human;
-//
-// Interfaces
use crate::interfaces::cat::ICat;
use crate::interfaces::dog::IDog;
use crate::interfaces::human::IHuman;
diff --git a/examples/factory/bootstrap.rs b/examples/factory/bootstrap.rs
index 19fad81..f8bef6e 100644
--- a/examples/factory/bootstrap.rs
+++ b/examples/factory/bootstrap.rs
@@ -4,11 +4,8 @@ use std::rc::Rc;
use syrette::ptr::TransientPtr;
use syrette::DIContainer;
-// Interfaces
use crate::interfaces::user::{IUser, IUserFactory};
use crate::interfaces::user_manager::IUserManager;
-//
-// Concrete implementations
use crate::user::User;
use crate::user_manager::UserManager;
@@ -20,14 +17,14 @@ pub fn bootstrap() -> Result<Rc<DIContainer>, Box<dyn Error>>
.bind::<dyn IUserManager>()
.to::<UserManager>()?;
- di_container.bind::<IUserFactory>().to_factory(
- &|name, date_of_birth, password| {
+ di_container.bind::<IUserFactory>().to_factory(&|_| {
+ Box::new(move |name, date_of_birth, password| {
let user: TransientPtr<dyn IUser> =
TransientPtr::new(User::new(name, date_of_birth, password));
user
- },
- )?;
+ })
+ })?;
Ok(di_container)
}
diff --git a/examples/factory/interfaces/user.rs b/examples/factory/interfaces/user.rs
index 70cd632..aafd0cb 100644
--- a/examples/factory/interfaces/user.rs
+++ b/examples/factory/interfaces/user.rs
@@ -1,5 +1,5 @@
use syrette::factory;
-use syrette::interfaces::factory::IFactory;
+use syrette::ptr::TransientPtr;
pub trait IUser
{
@@ -10,4 +10,4 @@ pub trait IUser
#[factory]
pub type IUserFactory =
- dyn IFactory<(&'static str, &'static str, &'static str), dyn IUser>;
+ dyn Fn(&'static str, &'static str, &'static str) -> TransientPtr<dyn IUser>;
diff --git a/examples/generics/bootstrap.rs b/examples/generics/bootstrap.rs
index 752a39b..98d03db 100644
--- a/examples/generics/bootstrap.rs
+++ b/examples/generics/bootstrap.rs
@@ -2,10 +2,7 @@ use std::rc::Rc;
use syrette::{di_container_bind, DIContainer};
-// Interfaces
use crate::interfaces::printer::IPrinter;
-//
-// Implementations
use crate::printer::Printer;
pub fn bootstrap() -> Rc<DIContainer>
diff --git a/examples/unbound/bootstrap.rs b/examples/unbound/bootstrap.rs
index 8df6678..04643dc 100644
--- a/examples/unbound/bootstrap.rs
+++ b/examples/unbound/bootstrap.rs
@@ -3,12 +3,9 @@ use std::rc::Rc;
use anyhow::Result;
use syrette::DIContainer;
-// Concrete implementations
use crate::animal_store::AnimalStore;
use crate::animals::dog::Dog;
use crate::animals::human::Human;
-//
-// Interfaces
use crate::interfaces::animal_store::IAnimalStore;
use crate::interfaces::dog::IDog;
use crate::interfaces::human::IHuman;
diff --git a/examples/with-3rd-party/bootstrap.rs b/examples/with-3rd-party/bootstrap.rs
index a4bd84a..c5512c4 100644
--- a/examples/with-3rd-party/bootstrap.rs
+++ b/examples/with-3rd-party/bootstrap.rs
@@ -5,10 +5,7 @@ use syrette::ptr::TransientPtr;
use syrette::{declare_default_factory, DIContainer};
use third_party_lib::Shuriken;
-// Interfaces
use crate::interfaces::ninja::INinja;
-//
-// Concrete implementations
use crate::ninja::Ninja;
declare_default_factory!(Shuriken);
@@ -21,7 +18,7 @@ pub fn bootstrap() -> Result<Rc<DIContainer>, Box<dyn Error>>
di_container
.bind::<Shuriken>()
- .to_default_factory(&|| TransientPtr::new(Shuriken::new()))?;
+ .to_default_factory(&|_| TransientPtr::new(Shuriken::new()))?;
Ok(di_container)
}
diff --git a/macros/src/factory_type_alias.rs b/macros/src/factory_type_alias.rs
index 8ea7baa..64afe57 100644
--- a/macros/src/factory_type_alias.rs
+++ b/macros/src/factory_type_alias.rs
@@ -1,17 +1,20 @@
+use quote::ToTokens;
use syn::parse::{Parse, ParseStream};
-use syn::{GenericArgument, ItemType, Path, Type, TypeParamBound, TypeTuple};
+use syn::punctuated::Punctuated;
+use syn::{parse, ItemType, Token, Type};
+
+use crate::fn_trait::FnTrait;
pub struct FactoryTypeAlias
{
pub type_alias: ItemType,
- pub factory_interface: Path,
- pub arg_types: TypeTuple,
+ pub factory_interface: FnTrait,
+ pub arg_types: Punctuated<Type, Token![,]>,
pub return_type: Type,
}
impl Parse for FactoryTypeAlias
{
- #[allow(clippy::match_wildcard_for_single_variants)]
fn parse(input: ParseStream) -> syn::Result<Self>
{
let type_alias = match input.parse::<ItemType>() {
@@ -19,66 +22,14 @@ impl Parse for FactoryTypeAlias
Err(_) => Err(input.error("Expected a type alias")),
}?;
- let aliased_trait = match &type_alias.ty.as_ref() {
- Type::TraitObject(alias_type) => Ok(alias_type),
- &_ => Err(input.error("Expected the aliased type to be a trait")),
- }?;
-
- if aliased_trait.bounds.len() != 1 {
- return Err(input.error("Expected the aliased trait to have a single bound."));
- }
-
- let bound_path = &match aliased_trait.bounds.first().unwrap() {
- TypeParamBound::Trait(trait_bound) => Ok(trait_bound),
- &_ => {
- Err(input.error("Expected the bound of the aliased trait to be a trait"))
- }
- }?
- .path;
-
- if bound_path.segments.is_empty()
- || bound_path.segments.last().unwrap().ident != "IFactory"
- {
- return Err(input
- .error("Expected the bound of the aliased trait to be 'dyn IFactory'"));
- }
-
- let angle_bracketed_args = match &bound_path.segments.last().unwrap().arguments {
- syn::PathArguments::AngleBracketed(angle_bracketed_args) => {
- Ok(angle_bracketed_args)
- }
- &_ => {
- Err(input.error("Expected angle bracketed arguments for 'dyn IFactory'"))
- }
- }?;
-
- let arg_types = match &angle_bracketed_args.args[0] {
- GenericArgument::Type(arg_types_type) => match arg_types_type {
- Type::Tuple(arg_types) => Ok(arg_types),
- &_ => Err(input.error(concat!(
- "Expected the first angle bracketed argument ",
- "of 'dyn IFactory' to be a type tuple"
- ))),
- },
- &_ => Err(input.error(concat!(
- "Expected the first angle bracketed argument ",
- "of 'dyn IFactory' to be a type"
- ))),
- }?;
-
- let return_type = match &angle_bracketed_args.args[1] {
- GenericArgument::Type(arg_type) => Ok(arg_type),
- &_ => Err(input.error(concat!(
- "Expected the second angle bracketed argument ",
- "of 'dyn IFactory' to be a type"
- ))),
- }?;
+ let aliased_fn_trait =
+ parse::<FnTrait>(type_alias.ty.as_ref().to_token_stream().into())?;
Ok(Self {
- type_alias: type_alias.clone(),
- factory_interface: bound_path.clone(),
- arg_types: arg_types.clone(),
- return_type: return_type.clone(),
+ type_alias,
+ factory_interface: aliased_fn_trait.clone(),
+ arg_types: aliased_fn_trait.inputs,
+ return_type: aliased_fn_trait.output,
})
}
}
diff --git a/macros/src/fn_trait.rs b/macros/src/fn_trait.rs
new file mode 100644
index 0000000..f9b3514
--- /dev/null
+++ b/macros/src/fn_trait.rs
@@ -0,0 +1,68 @@
+use quote::ToTokens;
+use syn::parse::Parse;
+use syn::punctuated::Punctuated;
+use syn::token::Paren;
+use syn::{parenthesized, Ident, Token, Type};
+
+/// A function trait. `dyn Fn(u32) -> String`
+#[derive(Debug, Clone)]
+pub struct FnTrait
+{
+ pub dyn_token: Token![dyn],
+ pub trait_ident: Ident,
+ pub paren_token: Paren,
+ pub inputs: Punctuated<Type, Token![,]>,
+ pub r_arrow_token: Token![->],
+ pub output: Type,
+}
+
+impl Parse for FnTrait
+{
+ fn parse(input: syn::parse::ParseStream) -> syn::Result<Self>
+ {
+ let dyn_token = input.parse::<Token![dyn]>()?;
+
+ let trait_ident = input.parse::<Ident>()?;
+
+ if trait_ident.to_string().as_str() != "Fn" {
+ return Err(syn::Error::new(trait_ident.span(), "Expected 'Fn'"));
+ }
+
+ let content;
+
+ let paren_token = parenthesized!(content in input);
+
+ let inputs = content.parse_terminated(Type::parse)?;
+
+ let r_arrow_token = input.parse::<Token![->]>()?;
+
+ let output = input.parse::<Type>()?;
+
+ Ok(Self {
+ dyn_token,
+ trait_ident,
+ paren_token,
+ inputs,
+ r_arrow_token,
+ output,
+ })
+ }
+}
+
+impl ToTokens for FnTrait
+{
+ fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream)
+ {
+ self.dyn_token.to_tokens(tokens);
+
+ self.trait_ident.to_tokens(tokens);
+
+ self.paren_token.surround(tokens, |tokens_inner| {
+ self.inputs.to_tokens(tokens_inner);
+ });
+
+ self.r_arrow_token.to_tokens(tokens);
+
+ self.output.to_tokens(tokens);
+ }
+}
diff --git a/macros/src/lib.rs b/macros/src/lib.rs
index 25f3c5c..4c815db 100644
--- a/macros/src/lib.rs
+++ b/macros/src/lib.rs
@@ -13,6 +13,7 @@ mod declare_interface_args;
mod dependency;
mod factory_macro_args;
mod factory_type_alias;
+mod fn_trait;
mod injectable_impl;
mod injectable_macro_args;
mod libs;
@@ -166,6 +167,7 @@ pub fn injectable(args_stream: TokenStream, impl_stream: TokenStream) -> TokenSt
/// ```
/// # use syrette::factory;
/// # use syrette::interfaces::factory::IFactory;
+/// # use syrette::ptr::TransientPtr;
/// #
/// # trait IConfigurator {}
/// #
@@ -182,7 +184,7 @@ pub fn injectable(args_stream: TokenStream, impl_stream: TokenStream) -> TokenSt
/// # impl IConfigurator for Configurator {}
/// #
/// #[factory]
-/// type IConfiguratorFactory = dyn IFactory<(Vec<String>,), dyn IConfigurator>;
+/// type IConfiguratorFactory = dyn Fn(Vec<String>) -> TransientPtr<dyn IConfigurator>;
/// ```
#[proc_macro_attribute]
#[cfg(feature = "factory")]
@@ -226,15 +228,18 @@ pub fn factory(args_stream: TokenStream, type_alias_stream: TokenStream) -> Toke
quote! {
syrette::declare_interface!(
syrette::castable_factory::blocking::CastableFactory<
- #arg_types,
- #return_type
- > -> #factory_interface
+ (std::rc::Rc<syrette::di_container::DIContainer>,),
+ #factory_interface
+ > -> syrette::interfaces::factory::IFactory<
+ (std::rc::Rc<syrette::di_container::DIContainer>,),
+ #factory_interface
+ >
);
syrette::declare_interface!(
syrette::castable_factory::blocking::CastableFactory<
- #arg_types,
- #return_type
+ (std::rc::Rc<syrette::di_container::DIContainer>,),
+ #factory_interface
> -> syrette::interfaces::any_factory::AnyFactory
);
}
@@ -315,14 +320,17 @@ pub fn declare_default_factory(args_stream: TokenStream) -> TokenStream
quote! {
syrette::declare_interface!(
syrette::castable_factory::blocking::CastableFactory<
- (),
+ (std::rc::Rc<syrette::di_container::DIContainer>,),
#interface,
- > -> syrette::interfaces::factory::IFactory<(), #interface>
+ > -> syrette::interfaces::factory::IFactory<
+ (std::rc::Rc<syrette::di_container::DIContainer>,),
+ #interface
+ >
);
syrette::declare_interface!(
syrette::castable_factory::blocking::CastableFactory<
- (),
+ (std::rc::Rc<syrette::di_container::DIContainer>,),
#interface,
> -> syrette::interfaces::any_factory::AnyFactory
);
diff --git a/src/di_container.rs b/src/di_container.rs
index ddd3a4f..532a905 100644
--- a/src/di_container.rs
+++ b/src/di_container.rs
@@ -249,27 +249,36 @@ where
#[cfg(feature = "factory")]
pub fn to_factory<Args, Return>(
&self,
- factory_func: &'static dyn Fn<Args, Output = crate::ptr::TransientPtr<Return>>,
+ factory_func: &'static dyn Fn<
+ (std::rc::Rc<DIContainer>,),
+ Output = Box<dyn Fn<Args, Output = crate::ptr::TransientPtr<Return>>>,
+ >,
) -> Result<BindingWhenConfigurator<Interface>, BindingBuilderError>
where
Args: 'static,
Return: 'static + ?Sized,
- Interface: crate::interfaces::factory::IFactory<Args, Return>,
+ Interface: Fn<Args, Output = crate::ptr::TransientPtr<Return>>,
{
- let mut bindings_mut = self.di_container.bindings.borrow_mut();
+ {
+ let bindings = self.di_container.bindings.borrow();
- if bindings_mut.has::<Interface>(None) {
- return Err(BindingBuilderError::BindingAlreadyExists(type_name::<
- Interface,
- >()));
+ if bindings.has::<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>(
None,
Box::new(crate::provider::blocking::FactoryProvider::new(
crate::ptr::FactoryPtr::new(factory_impl),
+ false,
)),
);
@@ -287,25 +296,34 @@ where
#[cfg(feature = "factory")]
pub fn to_default_factory<Return>(
&self,
- factory_func: &'static dyn Fn<(), Output = crate::ptr::TransientPtr<Return>>,
+ factory_func: &'static dyn Fn<
+ (Rc<DIContainer>,),
+ Output = crate::ptr::TransientPtr<Return>,
+ >,
) -> Result<BindingWhenConfigurator<Interface>, BindingBuilderError>
where
Return: 'static + ?Sized,
{
- let mut bindings_mut = self.di_container.bindings.borrow_mut();
+ {
+ let bindings = self.di_container.bindings.borrow();
- if bindings_mut.has::<Interface>(None) {
- return Err(BindingBuilderError::BindingAlreadyExists(type_name::<
- Interface,
- >()));
+ if bindings.has::<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>(
None,
Box::new(crate::provider::blocking::FactoryProvider::new(
crate::ptr::FactoryPtr::new(factory_impl),
+ true,
)),
);
@@ -381,10 +399,11 @@ impl DIContainer
let binding_providable =
self.get_binding_providable::<Interface>(name, dependency_history)?;
- Self::handle_binding_providable(binding_providable)
+ self.handle_binding_providable(binding_providable)
}
fn handle_binding_providable<Interface>(
+ self: &Rc<Self>,
binding_providable: Providable,
) -> Result<SomePtr<Interface>, DIContainerError>
where
@@ -409,21 +428,29 @@ impl DIContainer
)),
#[cfg(feature = "factory")]
Providable::Factory(factory_binding) => {
- match factory_binding.clone().cast::<Interface>() {
- Ok(factory) => Ok(SomePtr::Factory(factory)),
- Err(_err) => {
- use crate::interfaces::factory::IFactory;
-
- let default_factory = factory_binding
- .cast::<dyn IFactory<(), Interface>>()
- .map_err(|_| DIContainerError::CastFailed {
- interface: type_name::<Interface>(),
- binding_kind: "factory",
- })?;
-
- Ok(SomePtr::Transient(default_factory()))
- }
- }
+ use crate::interfaces::factory::IFactory;
+
+ let factory = factory_binding
+ .cast::<dyn IFactory<(Rc<DIContainer>,), Interface>>()
+ .map_err(|_| DIContainerError::CastFailed {
+ interface: type_name::<Interface>(),
+ binding_kind: "factory",
+ })?;
+
+ Ok(SomePtr::Factory(factory(self.clone()).into()))
+ }
+ #[cfg(feature = "factory")]
+ Providable::DefaultFactory(factory_binding) => {
+ use crate::interfaces::factory::IFactory;
+
+ let default_factory = factory_binding
+ .cast::<dyn IFactory<(Rc<DIContainer>,), Interface>>()
+ .map_err(|_| DIContainerError::CastFailed {
+ interface: type_name::<Interface>(),
+ binding_kind: "default factory",
+ })?;
+
+ Ok(SomePtr::Transient(default_factory(self.clone())))
}
}
}
@@ -690,12 +717,16 @@ mod tests
assert_eq!(di_container.bindings.borrow().count(), 0);
- di_container.bind::<IUserManagerFactory>().to_factory(&|| {
- let user_manager: TransientPtr<dyn subjects::IUserManager> =
- TransientPtr::new(subjects::UserManager::new());
+ di_container
+ .bind::<IUserManagerFactory>()
+ .to_factory(&|_| {
+ Box::new(move || {
+ let user_manager: TransientPtr<dyn subjects::IUserManager> =
+ TransientPtr::new(subjects::UserManager::new());
- user_manager
- })?;
+ user_manager
+ })
+ })?;
assert_eq!(di_container.bindings.borrow().count(), 1);
@@ -715,11 +746,13 @@ mod tests
di_container
.bind::<IUserManagerFactory>()
- .to_factory(&|| {
- let user_manager: TransientPtr<dyn subjects::IUserManager> =
- TransientPtr::new(subjects::UserManager::new());
+ .to_factory(&|_| {
+ Box::new(move || {
+ let user_manager: TransientPtr<dyn subjects::IUserManager> =
+ TransientPtr::new(subjects::UserManager::new());
- user_manager
+ user_manager
+ })
})?
.when_named("awesome")?;
@@ -901,6 +934,8 @@ mod tests
#[cfg(feature = "factory")]
fn can_get_factory() -> Result<(), Box<dyn Error>>
{
+ use crate::ptr::FactoryPtr;
+
trait IUserManager
{
fn add_user(&mut self, user_id: i128);
@@ -940,8 +975,7 @@ mod tests
use crate as syrette;
#[crate::factory]
- type IUserManagerFactory =
- dyn crate::interfaces::factory::IFactory<(Vec<i128>,), dyn IUserManager>;
+ type IUserManagerFactory = dyn Fn(Vec<i128>) -> TransientPtr<dyn IUserManager>;
mock! {
Provider {}
@@ -958,17 +992,26 @@ mod tests
let di_container = DIContainer::new();
- let mut mock_provider = MockProvider::new();
+ let factory_func: &'static dyn Fn<
+ (std::rc::Rc<DIContainer>,),
+ Output = Box<
+ dyn Fn<(Vec<i128>,), Output = crate::ptr::TransientPtr<dyn IUserManager>>,
+ >,
+ > = &|_: Rc<DIContainer>| {
+ Box::new(move |users| {
+ let user_manager: TransientPtr<dyn IUserManager> =
+ TransientPtr::new(UserManager::new(users));
- mock_provider.expect_provide().returning(|_, _| {
- Ok(Providable::Factory(crate::ptr::FactoryPtr::new(
- CastableFactory::new(&|users| {
- let user_manager: TransientPtr<dyn IUserManager> =
- TransientPtr::new(UserManager::new(users));
+ user_manager
+ })
+ };
- user_manager
- }),
- )))
+ let mut mock_provider = MockProvider::new();
+
+ mock_provider.expect_provide().returning_st(|_, _| {
+ Ok(Providable::Factory(FactoryPtr::new(CastableFactory::new(
+ factory_func,
+ ))))
});
di_container
@@ -985,6 +1028,8 @@ mod tests
#[cfg(feature = "factory")]
fn can_get_factory_named() -> Result<(), Box<dyn Error>>
{
+ use crate::ptr::FactoryPtr;
+
trait IUserManager
{
fn add_user(&mut self, user_id: i128);
@@ -1024,8 +1069,7 @@ mod tests
use crate as syrette;
#[crate::factory]
- type IUserManagerFactory =
- dyn crate::interfaces::factory::IFactory<(Vec<i128>,), dyn IUserManager>;
+ type IUserManagerFactory = dyn Fn(Vec<i128>) -> TransientPtr<dyn IUserManager>;
mock! {
Provider {}
@@ -1042,17 +1086,26 @@ mod tests
let di_container = DIContainer::new();
- let mut mock_provider = MockProvider::new();
+ let factory_func: &'static dyn Fn<
+ (std::rc::Rc<DIContainer>,),
+ Output = Box<
+ dyn Fn<(Vec<i128>,), Output = crate::ptr::TransientPtr<dyn IUserManager>>,
+ >,
+ > = &|_: Rc<DIContainer>| {
+ Box::new(move |users| {
+ let user_manager: TransientPtr<dyn IUserManager> =
+ TransientPtr::new(UserManager::new(users));
- mock_provider.expect_provide().returning(|_, _| {
- Ok(Providable::Factory(crate::ptr::FactoryPtr::new(
- CastableFactory::new(&|users| {
- let user_manager: TransientPtr<dyn IUserManager> =
- TransientPtr::new(UserManager::new(users));
+ user_manager
+ })
+ };
- user_manager
- }),
- )))
+ let mut mock_provider = MockProvider::new();
+
+ mock_provider.expect_provide().returning_st(|_, _| {
+ Ok(Providable::Factory(FactoryPtr::new(CastableFactory::new(
+ factory_func,
+ ))))
});
di_container
diff --git a/src/provider/blocking.rs b/src/provider/blocking.rs
index 69bbe78..e00786b 100644
--- a/src/provider/blocking.rs
+++ b/src/provider/blocking.rs
@@ -14,6 +14,10 @@ pub enum Providable
Singleton(SingletonPtr<dyn Injectable>),
#[cfg(feature = "factory")]
Factory(crate::ptr::FactoryPtr<dyn crate::interfaces::any_factory::AnyFactory>),
+ #[cfg(feature = "factory")]
+ DefaultFactory(
+ crate::ptr::FactoryPtr<dyn crate::interfaces::any_factory::AnyFactory>,
+ ),
}
pub trait IProvider
@@ -96,6 +100,7 @@ where
pub struct FactoryProvider
{
factory: crate::ptr::FactoryPtr<dyn crate::interfaces::any_factory::AnyFactory>,
+ is_default_factory: bool,
}
#[cfg(feature = "factory")]
@@ -103,9 +108,13 @@ impl FactoryProvider
{
pub fn new(
factory: crate::ptr::FactoryPtr<dyn crate::interfaces::any_factory::AnyFactory>,
+ is_default_factory: bool,
) -> Self
{
- Self { factory }
+ Self {
+ factory,
+ is_default_factory,
+ }
}
}
@@ -118,6 +127,10 @@ impl IProvider for FactoryProvider
_dependency_history: Vec<&'static str>,
) -> Result<Providable, InjectableError>
{
- Ok(Providable::Factory(self.factory.clone()))
+ Ok(if self.is_default_factory {
+ Providable::DefaultFactory(self.factory.clone())
+ } else {
+ Providable::Factory(self.factory.clone())
+ })
}
}