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_keyed_any_key(
155        &self,
156        key: &str,
157        variant: &crate::key::ServiceKey,
158    ) -> Option<Arc<dyn Any + Send + Sync>> {
159        self.child
160            .get_keyed_any_key(key, variant)
161            .or_else(|| self.root.get_keyed_any_key(key, variant))
162    }
163    fn try_get_keyed_any_result_key(
164        &self,
165        key: &str,
166        variant: &crate::key::ServiceKey,
167    ) -> Result<Option<Arc<dyn Any + Send + Sync>>, RdiError> {
168        match self.child.try_get_keyed_any_result_key(key, variant) {
169            Ok(Some(v)) => Ok(Some(v)),
170            _ => self.root.try_get_keyed_any_result_key(key, variant),
171        }
172    }
173    fn get_keyed_owned_any_key(
174        &self,
175        key: &str,
176        variant: &crate::key::ServiceKey,
177    ) -> Option<Arc<dyn Any + Send + Sync>> {
178        self.child
179            .get_keyed_owned_any_key(key, variant)
180            .or_else(|| self.root.get_keyed_owned_any_key(key, variant))
181    }
182    fn try_get_keyed_owned_any_key(
183        &self,
184        key: &str,
185        variant: &crate::key::ServiceKey,
186    ) -> Result<Option<Arc<dyn Any + Send + Sync>>, RdiError> {
187        match self.child.try_get_keyed_owned_any_key(key, variant) {
188            Ok(Some(v)) => Ok(Some(v)),
189            _ => self.root.try_get_keyed_owned_any_key(key, variant),
190        }
191    }
192    fn get_by_type_id(&self, tid: TypeId) -> Option<Arc<dyn Any + Send + Sync>> {
193        self.child
194            .get_by_type_id(tid)
195            .or_else(|| self.root.get_by_type_id(tid))
196    }
197    fn get_keyed_by_type_id(&self, tid: TypeId, key: &str) -> Option<Arc<dyn Any + Send + Sync>> {
198        self.child
199            .get_keyed_by_type_id(tid, key)
200            .or_else(|| self.root.get_keyed_by_type_id(tid, key))
201    }
202    fn get_all_any(&self, key: &str) -> Vec<Arc<dyn Any + Send + Sync>> {
203        // 合并 child + root(非 keyed):与 inherent `get_all` 的 child-then-root 顺序一致。
204        let mut result = IServiceResolver::get_all_any(self.child.as_ref(), key);
205        result.extend(IServiceResolver::get_all_any(self.root.as_ref(), key));
206        result
207    }
208    fn get_all_keyed_any(&self, key: &str) -> Vec<Arc<dyn Any + Send + Sync>> {
209        let mut result = IServiceResolver::get_all_keyed_any(self.child.as_ref(), key);
210        result.extend(IServiceResolver::get_all_keyed_any(self.root.as_ref(), key));
211        result
212    }
213    fn get_all_any_result(&self, key: &str) -> Result<Vec<Arc<dyn Any + Send + Sync>>, RdiError> {
214        let mut result = IServiceResolver::get_all_any_result(self.child.as_ref(), key)?;
215        result.extend(IServiceResolver::get_all_any_result(
216            self.root.as_ref(),
217            key,
218        )?);
219        Ok(result)
220    }
221    fn get_owned_any(&self, key: &str) -> Option<Arc<dyn Any + Send + Sync>> {
222        IServiceResolver::get_owned_any(self.child.as_ref(), key)
223            .or_else(|| IServiceResolver::get_owned_any(self.root.as_ref(), key))
224    }
225    fn try_get_any_result(
226        &self,
227        key: &str,
228    ) -> Result<Option<Arc<dyn Any + Send + Sync>>, RdiError> {
229        match self.child.try_get_any_result(key) {
230            Ok(Some(v)) => Ok(Some(v)),
231            _ => self.root.try_get_any_result(key),
232        }
233    }
234    fn try_get_keyed_any_result(
235        &self,
236        key: &str,
237        variant: &str,
238    ) -> Result<Option<Arc<dyn Any + Send + Sync>>, RdiError> {
239        match self.child.try_get_keyed_any_result(key, variant) {
240            Ok(Some(v)) => Ok(Some(v)),
241            _ => self.root.try_get_keyed_any_result(key, variant),
242        }
243    }
244    fn get_keyed_owned_any(&self, key: &str, variant: &str) -> Option<Arc<dyn Any + Send + Sync>> {
245        IServiceResolver::get_keyed_owned_any(self.child.as_ref(), key, variant)
246            .or_else(|| IServiceResolver::get_keyed_owned_any(self.root.as_ref(), key, variant))
247    }
248    fn provider_arc(&self) -> Option<Arc<ServiceProvider>> {
249        Some(Arc::clone(&self.child))
250    }
251}
252
253impl ServiceProviderWrapper {
254    /// Register a named service (for [`IProvider`](crate::bridge::IProvider) trait).
255    pub fn rdi_register_named(&self, name: &str, service: Arc<dyn Any + Send + Sync>) {
256        self.child.rdi_register_named(name, service);
257    }
258
259    /// Remove a named service (for [`IProvider`](crate::bridge::IProvider) trait).
260    pub fn rdi_remove_named(&self, name: &str) {
261        self.child.rdi_remove_named(name);
262    }
263}
264
265#[cfg(test)]
266mod tests {
267    use super::*;
268    use crate::collection::ServiceCollection;
269    #[derive(Debug, PartialEq)]
270    struct PO;
271    #[derive(Debug, PartialEq)]
272    struct RO {
273        v: i32,
274    }
275    #[derive(Debug, PartialEq)]
276    struct B {
277        s: String,
278    }
279    #[test]
280    fn child_prio() {
281        let r = ServiceCollection::new()
282            .singleton(|_| Arc::new(B { s: "root".into() }))
283            .build()
284            .unwrap();
285        let c = ServiceCollection::new()
286            .singleton(|_| Arc::new(B { s: "child".into() }))
287            .build()
288            .unwrap();
289        let w = ServiceProviderWrapper::new(c, r);
290        assert_eq!(w.get::<B>().unwrap().s, "child");
291    }
292    #[test]
293    fn root_fallback() {
294        let r = ServiceCollection::new()
295            .singleton(|_| Arc::new(RO { v: 42 }))
296            .build()
297            .unwrap();
298        let c = ServiceCollection::new().build().unwrap();
299        let w = ServiceProviderWrapper::new(c, r);
300        assert_eq!(w.get::<RO>().unwrap().v, 42);
301    }
302    #[test]
303    fn child_invisible() {
304        let r = ServiceCollection::new().build().unwrap();
305        let c = ServiceCollection::new()
306            .singleton(|_| Arc::new(PO))
307            .build()
308            .unwrap();
309        let _w = ServiceProviderWrapper::new(c, r.clone());
310        assert!(r.get_optional::<PO>().is_none());
311    }
312}