elif_core/container/
examples.rs1use crate::container::{IocContainerBuilder, ServiceBinder};
4use crate::errors::CoreError;
5use std::sync::Arc;
6
7pub trait UserRepository: Send + Sync {
9 fn find_by_id(&self, id: u32) -> Option<String>;
10 fn create(&self, name: &str) -> Result<u32, String>;
11}
12
13#[derive(Default)]
15pub struct PostgresUserRepository {
16 connection_string: String,
17}
18
19unsafe impl Send for PostgresUserRepository {}
20unsafe impl Sync for PostgresUserRepository {}
21
22impl PostgresUserRepository {
23 pub fn new(connection_string: String) -> Self {
24 Self { connection_string }
25 }
26}
27
28impl UserRepository for PostgresUserRepository {
29 fn find_by_id(&self, id: u32) -> Option<String> {
30 Some(format!("User {} from {}", id, self.connection_string))
31 }
32
33 fn create(&self, _name: &str) -> Result<u32, String> {
34 Ok(42) }
36}
37
38#[derive(Default)]
40pub struct UserService {
41 }
43
44unsafe impl Send for UserService {}
45unsafe impl Sync for UserService {}
46
47impl UserService {
48 pub fn get_user(&self, id: u32) -> Option<String> {
49 Some(format!("User {}", id))
51 }
52}
53
54pub fn basic_container_example() -> Result<(), CoreError> {
56 let mut builder = IocContainerBuilder::new();
57
58 builder
60 .bind_singleton::<PostgresUserRepository, PostgresUserRepository>()
61 .bind::<UserService, UserService>();
62
63 let container = builder.build()?;
65
66 let repo = container.resolve::<PostgresUserRepository>()?;
68 let user = repo.find_by_id(1);
69 assert!(user.is_some());
70
71 let service = container.resolve::<UserService>()?;
72 let user_data = service.get_user(1);
73 assert!(user_data.is_some());
74
75 Ok(())
76}
77
78pub fn named_services_example() -> Result<(), CoreError> {
80 let mut builder = IocContainerBuilder::new();
81
82 builder
84 .bind_named::<PostgresUserRepository, PostgresUserRepository>("primary")
85 .bind_named::<PostgresUserRepository, PostgresUserRepository>("backup");
86
87 let container = builder.build()?;
88
89 let primary_repo = container.resolve_named::<PostgresUserRepository>("primary")?;
91 let backup_repo = container.resolve_named::<PostgresUserRepository>("backup")?;
92
93 assert!(primary_repo.find_by_id(1).is_some());
94 assert!(backup_repo.find_by_id(1).is_some());
95
96 Ok(())
97}
98
99pub fn factory_services_example() -> Result<(), CoreError> {
101 let mut builder = IocContainerBuilder::new();
102
103 builder.bind_factory::<PostgresUserRepository, _, _>(|| {
105 Ok(PostgresUserRepository::new(
106 "postgres://localhost/db".to_string(),
107 ))
108 });
109
110 let container = builder.build()?;
111
112 let repo = container.resolve::<PostgresUserRepository>()?;
113 assert!(repo.find_by_id(1).is_some());
114
115 Ok(())
116}
117
118pub fn lifetime_example() -> Result<(), CoreError> {
120 let mut builder = IocContainerBuilder::new();
121
122 builder.bind_singleton::<UserService, UserService>();
124
125 builder.bind_transient::<PostgresUserRepository, PostgresUserRepository>();
127
128 let container = builder.build()?;
129
130 let service1 = container.resolve::<UserService>()?;
132 let service2 = container.resolve::<UserService>()?;
133 assert!(Arc::ptr_eq(&service1, &service2));
134
135 let repo1 = container.resolve::<PostgresUserRepository>()?;
137 let repo2 = container.resolve::<PostgresUserRepository>()?;
138 assert!(!Arc::ptr_eq(&repo1, &repo2));
139
140 Ok(())
141}
142
143#[cfg(test)]
144mod tests {
145 use super::*;
146
147 #[test]
148 fn test_basic_container_example() {
149 basic_container_example().unwrap();
150 }
151
152 #[test]
153 fn test_named_services_example() {
154 named_services_example().unwrap();
155 }
156
157 #[test]
158 fn test_factory_services_example() {
159 factory_services_example().unwrap();
160 }
161
162 #[test]
163 fn test_lifetime_example() {
164 lifetime_example().unwrap();
165 }
166}