Skip to main content

rust_dicore/
entry.rs

1use crate::lifetime::ServiceLifetime;
2use std::any::Any;
3use std::sync::Arc;
4
5/// Service resolver trait — the core DI resolution interface.
6///
7/// Provides both type-erased and generic resolution methods.
8pub trait IServiceResolver: Send + Sync {
9    fn get_any(&self, key: &str) -> Option<Arc<dyn Any + Send + Sync>>;
10    fn get_keyed_any(&self, key: &str, variant: &str) -> Option<Arc<dyn Any + Send + Sync>>;
11
12    /// Resolve a service by type (concrete or `dyn Trait`).
13    /// Panics if not registered.
14    fn get<T: ?Sized + Sync + Send + 'static>(&self) -> Arc<T>
15    where
16        Self: Sized,
17    {
18        self.get_any(std::any::type_name::<T>())
19            .and_then(|a| a.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d)))
20            .unwrap_or_else(|| panic!("service not registered: {}", std::any::type_name::<T>()))
21    }
22
23    /// Resolve a service by type, returning `None` if not registered.
24    fn try_get<T: ?Sized + Sync + Send + 'static>(&self) -> Option<Arc<T>>
25    where
26        Self: Sized,
27    {
28        self.get_any(std::any::type_name::<T>())
29            .and_then(|a| a.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d)))
30    }
31
32    /// Resolve a keyed service by type and key. Panics if not found.
33    fn get_keyed<T: ?Sized + Sync + Send + 'static>(&self, variant: &str) -> Arc<T>
34    where
35        Self: Sized,
36    {
37        self.get_keyed_any(std::any::type_name::<T>(), variant)
38            .and_then(|a| a.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d)))
39            .unwrap_or_else(|| {
40                panic!(
41                    "keyed service not registered: {}:{}",
42                    std::any::type_name::<T>(),
43                    variant
44                )
45            })
46    }
47
48    /// Resolve a keyed service by type and key, returning `None` if not found.
49    fn try_get_keyed<T: ?Sized + Sync + Send + 'static>(&self, variant: &str) -> Option<Arc<T>>
50    where
51        Self: Sized,
52    {
53        self.get_keyed_any(std::any::type_name::<T>(), variant)
54            .and_then(|a| a.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d)))
55    }
56}
57
58pub struct ServiceEntry {
59    pub cache_key: usize,
60    pub key: Option<String>,
61    pub type_name: &'static str, // kept for IServiceLocator string-based resolution
62    pub factory: ServiceFactory,
63    pub lifetime: ServiceLifetime,
64}
65
66pub type ServiceFactory =
67    Arc<dyn Fn(&dyn IServiceResolver) -> Arc<dyn Any + Send + Sync> + Send + Sync>;