Injection - 依赖注入容器
Injection 是一个基于宏的异步依赖注入容器,专为 Rust 应用程序设计。它使用 inventory 宏自动收集 Bean 定义,支持异步初始化和配置管理。
功能特性
- 自动注册:使用
#[derive(Component)]或#[derive(Service)]宏自动注册组件 - 异步初始化:支持异步工厂函数初始化组件
- 配置管理:通过
#[configuration]宏从配置文件加载配置 - 依赖注入:自动解决依赖关系,支持字段级注入
- 线程安全:所有组件都是
Send + Sync的 - 延迟初始化:使用
OnceCell实现懒加载 - Axum 集成:Service 宏支持 Axum 提取器,可直接在路由中使用
安装
在 Cargo.toml 中添加:
[]
= { = "*" }
= { = "1", = ["rt-multi-thread", "macros"] }
= { = "1", = ["derive"] }
基本用法
1. 定义组件
使用 #[derive(Component)] 或 #[derive(Service)] 宏标记结构体:
use ;
use Deserialize;
// 简单的数据访问对象
// 服务层组件,自动注入 DatabaseConnection
// Service 宏还支持 Axum 提取器,可直接在路由中使用
2. 初始化容器和使用组件
use InjectionContainer;
async
3. 使用配置
创建配置文件 application.toml:
[]
= "localhost"
= 5432
= "mydb"
[]
= 8080
定义配置结构体:
use ;
use Deserialize;
// 使用 #[configuration] 宏标记配置结构体
// 可以指定 prefix 参数,默认为结构体名称的下划线格式
// 如果不指定 prefix,默认使用结构体名称的下划线格式
// 例如:ServerConfig 默认为 "server_config"
// 在组件中使用配置
高级用法
使用 init 宏
#[init] 宏可以为异步函数自动生成无参版本,支持依赖注入:
use ;
// 原始异步函数,参数会自动注入
async
// 宏会生成一个 __initialize_database 无参函数
// 自动注入所有依赖并调用原始函数
自定义初始化逻辑
use Component;
// 为单元结构体提供自定义实现
API
InjectionContainer
async init<F: FnOnce()>(init_fn: impl Into<Option<F>>)- 异步初始化容器,可选的初始化回调instance()- 获取容器实例(同步)get<T: Component>()- 获取组件(同步,要求组件已初始化)get_async<T: Component>()- 获取组件(异步,可等待未初始化的组件)
宏
#[derive(Component)]
为结构体自动生成 Component trait 实现。
支持的字段属性:
#[config]- 从配置文件加载字段值#[init("fn_name")]- 使用指定的异步函数初始化字段
#[derive(Service)]
与 Component 相同,但额外实现 Axum 提取器,可在路由处理器中直接使用。
#[configuration(prefix = "xxx")]
为配置结构体实现 Configure trait。
- 可选参数
prefix指定配置文件中的键前缀 - 默认使用结构体名称的下划线格式(驼峰转下划线)
- 示例:
#[configuration(prefix = "database")]- 明确指定前缀为 "database"#[configuration]- 使用默认前缀,如ServerConfig-> "server_config"
#[init]
为异步函数生成无参版本,自动注入依赖。
- 支持
#[config]参数属性,从配置加载参数
错误处理
- 容器未初始化时调用
get()会 panic - 获取不存在的组件会 panic
- Bean 无法 downcast 会 panic
- 配置文件不存在会使用默认值或使用回退配置
特性标志
full- 启用所有功能(默认)clap-config- 支持命令行参数解析配置文件路径config- 启用配置管理功能serde- 启用序列化/反序列化支持
完整示例
use ;
use Deserialize;
// 配置
// 数据库连接
// 用户服务
// 控制器(可用于 Axum)
async
许可证
MIT