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