Injection - 依赖注入容器
Injection 是一个轻量级的依赖注入容器,用于 Rust 应用程序。它支持实例注入和类型注入(延迟初始化),能够管理复杂的依赖关系。
功能特性
- 实例注入:直接注入已创建的实例
- 类型注入:通过工厂函数延迟初始化类型
- 依赖管理:自动解决依赖关系
- 循环依赖检测:防止循环依赖导致的问题
- 类型安全:基于 Rust 的类型系统确保类型安全
安装
在 Cargo.toml 中添加:
[dependencies]
injection = { path = "./crates/injection" }
基本用法
use injection::{InjectionContainer, inject};
use anyhow::Result;
#[derive(Clone)]
struct DatabaseConnection {
url: String,
}
impl DatabaseConnection {
fn new(url: String) -> Self {
DatabaseConnection { url }
}
}
struct UserService {
db: DatabaseConnection,
}
impl UserService {
fn new(db: DatabaseConnection) -> Self {
UserService { db }
}
}
fn main() -> Result<()> {
let mut container = InjectionContainer::new();
let db = DatabaseConnection::new("localhost:5432".to_string());
container.provide_instance(db)?;
container.provide_type::<UserService, _>(|container| {
let db = container.get::<DatabaseConnection>()?.clone();
Ok(UserService::new(db))
})?;
let user_service = container.get::<UserService>()?;
Ok(())
}
使用宏
Injection 提供了 inject! 宏来简化注入过程:
use injection::{InjectionContainer, inject};
let mut container = InjectionContainer::new();
inject!(instance container, DatabaseConnection = DatabaseConnection::new("localhost:3306".to_string()));
inject!(type container, UserService = |container: &mut InjectionContainer| -> UserService {
let db = container.get::<DatabaseConnection>()?.clone();
Ok(UserService::new(db))
});
复杂依赖示例
对于具有多层依赖关系的系统,Injection 可以自动解决依赖:
API
InjectionContainer
new() - 创建新的容器实例
provide_instance<T>(instance: T) - 注入一个实例
provide_type<T, F>(factory: F) - 注入一个类型,使用工厂函数进行延迟初始化
get<T>() - 获取类型的不可变引用
get_mut<T>() - 获取类型的可变引用
has<T>() - 检查类型是否已注册
错误处理
Injection 使用 anyhow::Result 进行错误处理,常见的错误包括:
- 尝试获取未注册的类型
- 检测到循环依赖
- 类型转换错误
许可证
MIT