1use crate::{InjectBuilder, ServiceLifetime};
2
3pub trait Injectable: Sized {
5 fn inject(lifetime: ServiceLifetime) -> InjectBuilder;
11
12 fn singleton() -> InjectBuilder {
14 Self::inject(ServiceLifetime::Singleton)
15 }
16
17 fn scoped() -> InjectBuilder {
19 Self::inject(ServiceLifetime::Scoped)
20 }
21
22 fn transient() -> InjectBuilder {
24 Self::inject(ServiceLifetime::Transient)
25 }
26}
27
28#[cfg(test)]
29mod tests {
30 use super::*;
31 use crate::{Activator, Mut, Ref, ServiceCollection};
32
33 #[cfg_attr(feature = "async", maybe_impl::traits(Send, Sync))]
34 trait TestService {}
35
36 #[cfg_attr(feature = "async", maybe_impl::traits(Send, Sync))]
37 trait OtherTestService {}
38
39 #[derive(Default)]
40 struct TestServiceImpl {}
41
42 struct OtherTestServiceImpl {
43 _service: Ref<dyn TestService>,
44 }
45
46 impl TestService for TestServiceImpl {}
47
48 impl Injectable for TestServiceImpl {
49 fn inject(lifetime: ServiceLifetime) -> InjectBuilder {
50 InjectBuilder::new(
51 Activator::new::<dyn TestService, Self>(
52 |_| Ref::new(Self::default()),
53 |_| Ref::new(Mut::new(Self::default())),
54 ),
55 lifetime,
56 )
57 }
58 }
59
60 impl OtherTestServiceImpl {
61 fn new(service: Ref<dyn TestService>) -> Self {
62 Self { _service: service }
63 }
64 }
65
66 impl Injectable for OtherTestServiceImpl {
67 fn inject(lifetime: ServiceLifetime) -> InjectBuilder {
68 InjectBuilder::new(
69 Activator::new::<dyn OtherTestService, Self>(
70 |sp| Ref::new(Self::new(sp.get_required::<dyn TestService>())),
71 |sp| Ref::new(Mut::new(Self::new(sp.get_required::<dyn TestService>()))),
72 ),
73 lifetime,
74 )
75 }
76 }
77
78 impl OtherTestService for OtherTestServiceImpl {}
79
80 #[test]
81 fn inject_should_invoke_constructor_injection() {
82 let services = ServiceCollection::new()
84 .add(TestServiceImpl::singleton())
85 .add(OtherTestServiceImpl::transient())
86 .build_provider()
87 .unwrap();
88
89 let service = services.get::<dyn OtherTestService>();
91
92 assert!(service.is_some());
94 }
95}