Skip to main content

rust_dix/
wrapper.rs

1use crate::entry::IServiceResolver;
2use crate::error::RdiError;
3use crate::provider::ServiceProvider;
4use std::any::{Any, TypeId};
5use std::sync::Arc;
6
7pub struct ServiceProviderWrapper {
8    child: Arc<ServiceProvider>,
9    root: Arc<ServiceProvider>,
10}
11
12impl ServiceProviderWrapper {
13    pub fn new(child: Arc<ServiceProvider>, root: Arc<ServiceProvider>) -> Arc<Self> {
14        Arc::new(Self { child, root })
15    }
16    pub fn child(&self) -> &Arc<ServiceProvider> {
17        &self.child
18    }
19    pub fn root(&self) -> &Arc<ServiceProvider> {
20        &self.root
21    }
22
23    pub fn get<T: ?Sized + Send + Sync + 'static>(&self) -> Result<Arc<T>, RdiError> {
24        // Child-first, root-fallback. Errors other than "not registered" (e.g.
25        // root scope validation) must not be masked as ServiceNotFound.
26        match self.child.get::<T>() {
27            Ok(v) => Ok(v),
28            Err(RdiError::ServiceNotFound { .. }) => self.root.get::<T>(),
29            Err(err) => Err(err),
30        }
31    }
32    pub fn get_optional<T: ?Sized + Send + Sync + 'static>(&self) -> Option<Arc<T>> {
33        self.try_get::<T>()
34    }
35    pub fn get_keyed<T: ?Sized + Send + Sync + 'static>(
36        &self,
37        key: &str,
38    ) -> Result<Arc<T>, RdiError> {
39        match self.child.get_keyed::<T>(key) {
40            Ok(v) => Ok(v),
41            Err(RdiError::KeyedServiceNotFound { .. }) => self.root.get_keyed::<T>(key),
42            Err(err) => Err(err),
43        }
44    }
45    pub fn get_all<T: ?Sized + Send + Sync + 'static>(&self) -> Vec<Arc<T>> {
46        let mut r = self.child.get_all::<T>();
47        r.extend(self.root.get_all::<T>());
48        r
49    }
50    /// Unkeyed + keyed registrations are kept separate (MEDI parity): this
51    /// returns child-then-root **keyed** instances only.
52    pub fn get_all_keyed<T: ?Sized + Send + Sync + 'static>(&self) -> Vec<Arc<T>> {
53        let mut r = self.child.get_all_keyed::<T>();
54        r.extend(self.root.get_all_keyed::<T>());
55        r
56    }
57    /// Whether `T` is registered in the child or the root (MEDI
58    /// `IServiceProviderIsService` parity).
59    pub fn is_registered<T: ?Sized + Send + Sync + 'static>(&self) -> bool {
60        self.child.is_registered::<T>() || self.root.is_registered::<T>()
61    }
62    /// Whether `T` is registered under `key` in the child or the root.
63    pub fn is_registered_keyed<T: ?Sized + Send + Sync + 'static>(&self, key: &str) -> bool {
64        self.child.is_registered_keyed::<T>(key) || self.root.is_registered_keyed::<T>(key)
65    }
66    pub fn get_named<T: Send + Sync + 'static>(&self, name: &str) -> Option<Arc<T>> {
67        self.child
68            .get_named::<T>(name)
69            .or_else(|| self.root.get_named::<T>(name))
70    }
71    pub fn get_named_any(&self, name: &str) -> Option<Arc<dyn Any + Send + Sync>> {
72        self.child
73            .get_named_any(name)
74            .or_else(|| self.root.get_named_any(name))
75    }
76
77    /// Resolve owned `T` (bypass cache, fresh each call). Child-first, root-fallback.
78    /// Returns `Err` if not registered or the service is Singleton.
79    pub fn get_owned<T: Send + Sync + 'static>(&self) -> Result<T, RdiError> {
80        let type_name = std::any::type_name::<T>();
81        self.try_get_owned::<T>()
82            .ok_or_else(|| RdiError::not_found(type_name, None))
83    }
84    /// Resolve owned `T`, returning `None` if not registered or Singleton.
85    pub fn try_get_owned<T: Send + Sync + 'static>(&self) -> Option<T> {
86        let arc_any =
87            IServiceResolver::get_owned_any(self.child.as_ref(), std::any::type_name::<T>())
88                .or_else(|| {
89                    IServiceResolver::get_owned_any(self.root.as_ref(), std::any::type_name::<T>())
90                })?;
91        let arc_t = crate::provider::ServiceProvider::extract::<T>(arc_any)?;
92        Arc::try_unwrap(arc_t).ok()
93    }
94    /// Resolve owned keyed `T`. Child-first, root-fallback.
95    pub fn get_keyed_owned<T: Send + Sync + 'static>(&self, key: &str) -> Result<T, RdiError> {
96        let type_name = std::any::type_name::<T>();
97        self.try_get_keyed_owned::<T>(key)
98            .ok_or_else(|| RdiError::keyed_not_found(type_name, key, None))
99    }
100    /// Resolve owned keyed `T`, returning `None` if not found or Singleton.
101    pub fn try_get_keyed_owned<T: Send + Sync + 'static>(&self, key: &str) -> Option<T> {
102        let arc_any = IServiceResolver::get_keyed_owned_any(
103            self.child.as_ref(),
104            std::any::type_name::<T>(),
105            key,
106        )
107        .or_else(|| {
108            IServiceResolver::get_keyed_owned_any(
109                self.root.as_ref(),
110                std::any::type_name::<T>(),
111                key,
112            )
113        })?;
114        let arc_t = crate::provider::ServiceProvider::extract::<T>(arc_any)?;
115        Arc::try_unwrap(arc_t).ok()
116    }
117
118    /// Resolve an async service by type. Child-first, root-fallback.
119    pub async fn get_async<T: ?Sized + Send + Sync + 'static>(&self) -> Result<Arc<T>, RdiError> {
120        match self.child.get_async::<T>().await {
121            Ok(svc) => Ok(svc),
122            Err(_) => self.root.get_async::<T>().await,
123        }
124    }
125    /// Resolve an async keyed service. Child-first, root-fallback.
126    pub async fn get_keyed_async<T: ?Sized + Send + Sync + 'static>(
127        &self,
128        key: &str,
129    ) -> Result<Arc<T>, RdiError> {
130        match self.child.get_keyed_async::<T>(key).await {
131            Ok(svc) => Ok(svc),
132            Err(_) => self.root.get_keyed_async::<T>(key).await,
133        }
134    }
135
136    fn try_get<T: ?Sized + Send + Sync + 'static>(&self) -> Option<Arc<T>> {
137        self.child
138            .get_optional::<T>()
139            .or_else(|| self.root.get_optional::<T>())
140    }
141}
142
143impl IServiceResolver for ServiceProviderWrapper {
144    fn get_any(&self, key: &str) -> Option<Arc<dyn Any + Send + Sync>> {
145        IServiceResolver::get_any(self.child.as_ref(), key)
146            .or_else(|| IServiceResolver::get_any(self.root.as_ref(), key))
147    }
148    fn get_keyed_any(&self, key: &str, variant: &str) -> Option<Arc<dyn Any + Send + Sync>> {
149        IServiceResolver::get_keyed_any(self.child.as_ref(), key, variant)
150            .or_else(|| IServiceResolver::get_keyed_any(self.root.as_ref(), key, variant))
151    }
152    fn get_by_type_id(&self, tid: TypeId) -> Option<Arc<dyn Any + Send + Sync>> {
153        self.child
154            .get_by_type_id(tid)
155            .or_else(|| self.root.get_by_type_id(tid))
156    }
157    fn get_keyed_by_type_id(&self, tid: TypeId, key: &str) -> Option<Arc<dyn Any + Send + Sync>> {
158        self.child
159            .get_keyed_by_type_id(tid, key)
160            .or_else(|| self.root.get_keyed_by_type_id(tid, key))
161    }
162    fn get_all_any(&self, key: &str) -> Vec<Arc<dyn Any + Send + Sync>> {
163        // 合并 child + root(非 keyed):与 inherent `get_all` 的 child-then-root 顺序一致。
164        let mut result = IServiceResolver::get_all_any(self.child.as_ref(), key);
165        result.extend(IServiceResolver::get_all_any(self.root.as_ref(), key));
166        result
167    }
168    fn get_all_keyed_any(&self, key: &str) -> Vec<Arc<dyn Any + Send + Sync>> {
169        let mut result = IServiceResolver::get_all_keyed_any(self.child.as_ref(), key);
170        result.extend(IServiceResolver::get_all_keyed_any(self.root.as_ref(), key));
171        result
172    }
173    fn get_all_any_result(&self, key: &str) -> Result<Vec<Arc<dyn Any + Send + Sync>>, RdiError> {
174        let mut result = IServiceResolver::get_all_any_result(self.child.as_ref(), key)?;
175        result.extend(IServiceResolver::get_all_any_result(
176            self.root.as_ref(),
177            key,
178        )?);
179        Ok(result)
180    }
181    fn get_owned_any(&self, key: &str) -> Option<Arc<dyn Any + Send + Sync>> {
182        IServiceResolver::get_owned_any(self.child.as_ref(), key)
183            .or_else(|| IServiceResolver::get_owned_any(self.root.as_ref(), key))
184    }
185    fn try_get_any_result(
186        &self,
187        key: &str,
188    ) -> Result<Option<Arc<dyn Any + Send + Sync>>, RdiError> {
189        match self.child.try_get_any_result(key) {
190            Ok(Some(v)) => Ok(Some(v)),
191            _ => self.root.try_get_any_result(key),
192        }
193    }
194    fn try_get_keyed_any_result(
195        &self,
196        key: &str,
197        variant: &str,
198    ) -> Result<Option<Arc<dyn Any + Send + Sync>>, RdiError> {
199        match self.child.try_get_keyed_any_result(key, variant) {
200            Ok(Some(v)) => Ok(Some(v)),
201            _ => self.root.try_get_keyed_any_result(key, variant),
202        }
203    }
204    fn get_keyed_owned_any(&self, key: &str, variant: &str) -> Option<Arc<dyn Any + Send + Sync>> {
205        IServiceResolver::get_keyed_owned_any(self.child.as_ref(), key, variant)
206            .or_else(|| IServiceResolver::get_keyed_owned_any(self.root.as_ref(), key, variant))
207    }
208    fn provider_arc(&self) -> Option<Arc<ServiceProvider>> {
209        Some(Arc::clone(&self.child))
210    }
211}
212
213impl ServiceProviderWrapper {
214    /// Register a named service (for [`IProvider`](crate::bridge::IProvider) trait).
215    pub fn rdi_register_named(&self, name: &str, service: Arc<dyn Any + Send + Sync>) {
216        self.child.rdi_register_named(name, service);
217    }
218
219    /// Remove a named service (for [`IProvider`](crate::bridge::IProvider) trait).
220    pub fn rdi_remove_named(&self, name: &str) {
221        self.child.rdi_remove_named(name);
222    }
223}
224
225#[cfg(test)]
226mod tests {
227    use super::*;
228    use crate::collection::ServiceCollection;
229    #[derive(Debug, PartialEq)]
230    struct PO;
231    #[derive(Debug, PartialEq)]
232    struct RO {
233        v: i32,
234    }
235    #[derive(Debug, PartialEq)]
236    struct B {
237        s: String,
238    }
239    #[test]
240    fn child_prio() {
241        let r = ServiceCollection::new()
242            .singleton(|_| Arc::new(B { s: "root".into() }))
243            .build()
244            .unwrap();
245        let c = ServiceCollection::new()
246            .singleton(|_| Arc::new(B { s: "child".into() }))
247            .build()
248            .unwrap();
249        let w = ServiceProviderWrapper::new(c, r);
250        assert_eq!(w.get::<B>().unwrap().s, "child");
251    }
252    #[test]
253    fn root_fallback() {
254        let r = ServiceCollection::new()
255            .singleton(|_| Arc::new(RO { v: 42 }))
256            .build()
257            .unwrap();
258        let c = ServiceCollection::new().build().unwrap();
259        let w = ServiceProviderWrapper::new(c, r);
260        assert_eq!(w.get::<RO>().unwrap().v, 42);
261    }
262    #[test]
263    fn child_invisible() {
264        let r = ServiceCollection::new().build().unwrap();
265        let c = ServiceCollection::new()
266            .singleton(|_| Arc::new(PO))
267            .build()
268            .unwrap();
269        let _w = ServiceProviderWrapper::new(c, r.clone());
270        assert!(r.get_optional::<PO>().is_none());
271    }
272}