dilib/
injectable.rs

1use crate::Container;
2
3/// A trait for constructing a type getting the dependencies from a `Container`.
4///
5/// # Example
6/// ```
7/// use std::sync::Mutex;
8/// use dilib::{Singleton, Inject, Container};
9///
10/// struct Greeter {
11///    message: String,
12///    total_greets: Singleton<Mutex<usize>>
13/// }
14///
15/// impl Greeter {
16///     fn greet(&self) {
17///         println!("{}", self.message);
18///         *self.total_greets.lock().unwrap() += 1;
19///     }
20/// }
21///
22/// impl Inject for Greeter {
23///     fn inject(container: &Container) -> Self{
24///         let message = container.get_scoped_with_name::<String>("es_msg").unwrap();
25///         let total_greets = container.get_singleton_with_name::<Mutex<usize>>("count").unwrap();
26///         Greeter { message, total_greets }
27///     }
28/// }
29/// ```
30pub trait Inject {
31    /// Constructs this type using the `Container`.
32    fn inject(container: &Container) -> Self;
33}
34
35impl<T: Default> Inject for T {
36    #[inline]
37    fn inject(_: &Container) -> Self {
38        Self::default()
39    }
40}
41
42/*
43Is not decided yet if is necessary to have an `TryInject` trait.
44
45When creating an instance from `Inject` there is only 2 options:
46or create the instance or panic, is expected to be deterministic,
47if we allow the operation to fail with an `Err` this open some questions:
48
49- Why want an instance that may not be created?
50- In which cases no creating an instance is something that should not panic?
51- Why not just implement Inject to a `struct Fallible<T>(Result<T, Error>)`?
52
53Checkout the related: `z_error.rs` and `z_typing.rs`
54*/
55
56// /// A trait for attempt to construct a type getting the dependencies from a `Container`.
57// pub trait TryInject: Sized {
58//     /// Attempts to constructs this type using the `Container`.
59//     fn try_inject(container: &Container) -> Result<Self, crate::error::ResolveError>;
60// }
61
62// impl<T: TryInject> Inject for T {
63//     #[inline]
64//     fn inject(container: &Container) -> Self {
65//         Self::try_inject(container).unwrap()
66//     }
67// }