Skip to main content

tx_di_core/
component.rs

1//! Component trait — 类型驱动的依赖注入核心
2//!
3//! 每个被 DI 管理的类型实现此 trait,用 associated type `Deps` 声明依赖。
4//! `#[derive(Component)]` 宏自动生成实现。
5
6use std::any::TypeId;
7use std::future::Future;
8use std::sync::Arc;
9
10use crate::error::AppError;
11use crate::scope::Scope;
12use crate::store::Store;
13
14/// 异步 Future 类型别名
15pub type BoxFuture<T> = std::pin::Pin<Box<dyn Future<Output = T> + Send>>;
16
17/// 组件 trait — 每个被 DI 管理的类型都实现此 trait
18///
19/// 用 `#[derive(Component)]` 自动生成(新宏),或手动实现。
20///
21/// # 核心设计
22///
23/// - `Deps` associated type 声明依赖,编译期类型可知
24/// - `build()` 是纯函数,从依赖构建自身
25/// - 生命周期钩子全部有默认实现
26///
27/// # 生命周期
28///
29/// 1. `build()` — 构造实例(由宏生成)
30/// 2. `inner_init()` — build 后同步初始化(可选)
31/// 3. `init()` — 同步初始化(可选)
32/// 4. `async_init()` — 异步初始化(可选)
33/// 5. `run()` — 异步运行,长期任务(可选)
34/// 6. `shutdown()` — 优雅关闭(可选)
35pub trait Component: Send + Sync + 'static {
36    /// 依赖元组,编译期类型可知
37    ///
38    /// 例如:`type Deps = (Arc<DbPool>, Arc<AppConfig>);`
39    ///
40    /// 无依赖时用 `()`。
41    type Deps: DepsTuple;
42
43    /// 从依赖构建组件实例
44    ///
45    /// 这是一个纯函数,不接触 Store,只接收已解析的依赖。
46    fn build(deps: Self::Deps) -> Self;
47
48    /// 作用域,默认 Singleton
49    const SCOPE: Scope = Scope::Singleton;
50
51    // ── 生命周期钩子(全部有默认实现)─────────────────────────────────
52
53    /// build 之后、init 之前调用(同步初始化)
54    ///
55    /// 可以访问 Store 注入额外依赖,但主要依赖应通过 `Deps` 声明。
56    #[allow(unused_variables)]
57    fn inner_init(&mut self, store: &Store) -> crate::RIE<()> {
58        Ok(())
59    }
60
61    /// 同步初始化(在 App 阶段调用)
62    ///
63    /// 可以访问整个 App,用于跨组件协作初始化。
64    #[allow(unused_variables)]
65    fn init(app: &Arc<crate::App>) -> crate::RIE<()> {
66        Ok(())
67    }
68
69    /// 异步初始化(在 tokio runtime 里调用)
70    #[allow(unused_variables)]
71    fn async_init(app: &Arc<crate::App>) -> BoxFuture<crate::RIE<()>> {
72        Box::pin(async { Ok(()) })
73    }
74
75    /// 异步运行(在独立 task 里调用,直到 CancellationToken 触发)
76    #[allow(unused_variables)]
77    fn async_run(app: &Arc<crate::App>, token: crate::CancellationToken) -> BoxFuture<crate::RIE<()>> {
78        Box::pin(async { Ok(()) })
79    }
80
81    /// 优雅关闭
82    #[allow(unused_variables)]
83    fn shutdown(&self) {}
84
85    /// 初始化排序(值越小越先执行,默认 10000)
86    fn init_sort() -> i32 {
87        10000
88    }
89
90    /// 返回此组件实现的 trait TypeId 列表
91    ///
92    /// 由 `#[component(as_trait = ...)]` 宏自动生成。
93    /// 默认为空 — 不实现任何 trait。
94    fn trait_impls() -> &'static [fn() -> TypeId] {
95        &[]
96    }
97}
98
99/// 依赖元组 trait — 用宏为不同元数自动实现
100///
101/// 从 Store 解析所有依赖,返回元组。
102pub trait DepsTuple: Sized {
103    /// 从 Store 解析所有依赖
104    fn resolve(store: &Store) -> Result<Self, AppError>;
105
106    /// 返回依赖的 TypeId 列表(用于拓扑排序)
107    fn dep_type_ids() -> Vec<TypeId>;
108}
109
110// ── 为元组自动实现 DepsTuple ──────────────────────────────────────────────
111
112impl DepsTuple for () {
113    fn resolve(_store: &Store) -> crate::RIE<Self> {
114        Ok(())
115    }
116
117    fn dep_type_ids() -> Vec<TypeId> {
118        Vec::new()
119    }
120}
121
122macro_rules! impl_deps_tuple {
123    ($($T:ident),+) => {
124        impl<$($T: Component),+> DepsTuple for ($(Arc<$T>,)+) {
125            fn resolve(store: &Store) -> Result<Self, AppError> {
126                Ok(($(
127                    store.inject::<$T>()?
128                ,)+))
129            }
130
131            fn dep_type_ids() -> Vec<TypeId> {
132                vec![$(TypeId::of::<$T>()),+]
133            }
134        }
135    };
136}
137
138impl_deps_tuple!(A);
139impl_deps_tuple!(A, B);
140impl_deps_tuple!(A, B, C);
141impl_deps_tuple!(A, B, C, D);
142impl_deps_tuple!(A, B, C, D, E);
143impl_deps_tuple!(A, B, C, D, E, F);
144impl_deps_tuple!(A, B, C, D, E, F, G);
145impl_deps_tuple!(A, B, C, D, E, F, G, H);
146impl_deps_tuple!(A, B, C, D, E, F, G, H, I);
147impl_deps_tuple!(A, B, C, D, E, F, G, H, I, J);
148impl_deps_tuple!(A, B, C, D, E, F, G, H, I, J, K);
149impl_deps_tuple!(A, B, C, D, E, F, G, H, I, J, K, L);
150impl_deps_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M);
151impl_deps_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
152impl_deps_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
153impl_deps_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);