use crate::rudi::dicontainer::direg;
use crate::rulog;
use std::sync::{Arc, Mutex};
// 单例 Bean 的统一 trait
pub trait BeanSingleton: Sized + Send + Sync + 'static {
/// 全局唯一标识
//const BEAN_NAME: &'static str;
fn bean_name() -> &'static str {
std::any::type_name::<Self>() // "rudi::di_example::DiExample" — 天然唯一!
}
/// 工厂方法
fn new_bean() -> Self;
/// 查找(统一返回 Arc<Mutex<Self>>)
fn find_bean() -> Option<Arc<Mutex<Self>>> {
rulog::info2("find_bean bean =》", Self::bean_name());
direg::get_bean::<Mutex<Self>>(Self::bean_name())
// direg::get_bean::<Mutex<Self>>(Self::BEAN_NAME)
}
/// 注册
fn register_bean() {
rulog::info2("register bean =》", Self::bean_name());
direg::register_singleton(Self::bean_name(), || Mutex::new(Self::new_bean()));
// direg::register_singleton(Self::BEAN_NAME, || Mutex::new(Self::new_bean()));
}
}
这篇文章介绍了一个使用Rust实现的依赖注入(DI)容器方案,主要包含以下内容:
-
定义了一个
BeanSingletontrait,为单例Bean提供统一接口,包括bean名称获取、创建、查找和注册方法。 -
展示了如何实现
BeanSingletontrait,以DBDao为例,通过register_bean()注册单例,使用find_bean()获取实例。 -
提供了线程安全的单例访问方式,使用
Arc<Mutex<T>>包装实例,确保并发安全。 -
演示了两种使用方式:
- 通过全局函数
find_bean_db_dao()获取实例 - 直接通过类型调用
DBDao::find_bean()
- 通过全局函数
该方案利用ctor宏实现自动注册,简化了依赖管理,适用于需要单例和依赖注入的场景。
生成注册代码
#[test]
fn test_05_rudi() {
find_bean_di_factroy().unwrap().lock().unwrap().make_di()
}

// pkg data::db_dao
/*
@Title 文件名称: db_dao_init.rs
@Desp 描述: 依赖自动注入
@Company 公司: wcht.akunlong.top
@Author 作者: raymond@163.com 时间: 2026-08-21 09:37:25
@Update 作者: raymond@163.com 时间: 2026-08-21 09:37:25
*/
use crate::data::db_dao::DBDao;
use crate::rubase::{BaseEntity, BeanSingleton};
use ctor::ctor;
use std::sync::{Arc, Mutex};
#[ctor(unsafe)]
pub fn init() {
DBDao::register_bean();
}
pub fn find_bean_db_dao() -> Option<Arc<Mutex<DBDao>>> {
DBDao::find_bean()
}
impl BeanSingleton for DBDao {
fn new_bean() -> Self {
let mut dao= DBDao::default();
dao.init();
dao
}
}
测试
#[test]
fn test_06_rudi() {
let s= find_bean_db_dao().unwrap() ;
println!("{}", s.lock().unwrap().test());
}
#[test]
fn test_07_rudi() {
let s= find_bean_db_dao().unwrap() ;
s.lock().unwrap().doSome();
}
结果:

使用方式1:
#[test]
fn test_07_rudi() {
let s= find_bean_db_dao().unwrap() ;
s.lock().unwrap().doSome();
}
使用方式2:
#[test]
fn test_08_rudi() {
let s= DBDao::find_bean().unwrap() ;
s.lock().unwrap().doSome();
}


876

被折叠的 条评论
为什么被折叠?



