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::*;
32
33 trait TestService {}
34 trait OtherTestService {}
35
36 #[derive(Default)]
37 struct TestServiceImpl {}
38 struct OtherTestServiceImpl {
39 _service: Ref<dyn TestService>,
40 }
41
42 impl TestService for TestServiceImpl {}
43
44 impl Injectable for TestServiceImpl {
45 fn inject(lifetime: ServiceLifetime) -> InjectBuilder {
46 InjectBuilder::new(
47 Activator::new::<dyn TestService, Self>(
48 |_| Ref::new(Self::default()),
49 |_| Ref::new(Mut::new(Self::default())),
50 ),
51 lifetime,
52 )
53 }
54 }
55
56 impl OtherTestServiceImpl {
57 fn new(service: Ref<dyn TestService>) -> Self {
58 Self { _service: service }
59 }
60 }
61
62 impl Injectable for OtherTestServiceImpl {
63 fn inject(lifetime: ServiceLifetime) -> InjectBuilder {
64 InjectBuilder::new(
65 Activator::new::<dyn OtherTestService, Self>(
66 |sp| Ref::new(Self::new(sp.get_required::<dyn TestService>())),
67 |sp| {
68 Ref::new(Mut::new(Self::new(sp.get_required::<dyn TestService>())))
69 },
70 ),
71 lifetime,
72 )
73 }
74 }
75
76 impl OtherTestService for OtherTestServiceImpl {}
77
78 #[test]
79 fn inject_should_invoke_constructor_injection() {
80 let services = ServiceCollection::new()
82 .add(TestServiceImpl::singleton())
83 .add(OtherTestServiceImpl::transient())
84 .build_provider()
85 .unwrap();
86
87 let service = services.get::<dyn OtherTestService>();
89
90 assert!(service.is_some());
92 }
93}