| Crates.io | rs-bean |
| lib.rs | rs-bean |
| version | 0.1.1 |
| created_at | 2026-01-21 15:14:18.503566+00 |
| updated_at | 2026-01-22 12:58:17.84505+00 |
| description | A lightweight Rust library for bean management |
| homepage | |
| repository | |
| max_upload_size | |
| id | 2059535 |
| size | 22,106 |
A lightweight Rust library for bean management and dependency injection.
⚠️ APIs are not stable yet; future releases may introduce breaking changes.
Arc and RwLock for concurrent accessAdd this to your Cargo.toml:
[dependencies]
rs-bean = "0.1.0"
use std::sync::Arc;
use rs_bean::bean::{BeanContainer, Scope};
// Define your services
struct Database {
connection_string: String,
}
impl Database {
fn new(connection_string: String) -> Self {
Database { connection_string }
}
fn query(&self, sql: &str) {
println!("Executing query on {}: {}", self.connection_string, sql);
}
}
struct UserService {
db: Arc<Database>,
}
impl UserService {
fn new(db: Arc<Database>) -> Self {
UserService { db }
}
fn get_user(&self, id: u32) {
self.db
.query(&format!("SELECT * FROM users WHERE id = {}", id));
}
}
struct OrderService {
db: Arc<Database>,
user_service: Arc<UserService>,
}
impl OrderService {
fn new(db: Arc<Database>, user_service: Arc<UserService>) -> Self {
OrderService { db, user_service }
}
fn create_order(&self, user_id: u32, product: &str) {
self.user_service.get_user(user_id);
self.db.query(&format!(
"INSERT INTO orders (user_id, product) VALUES ({}, '{}')",
user_id, product
));
}
}
fn main() -> Result<(), String> {
// Create container
let container = BeanContainer::new();
// Register Database (Singleton)
container.register::<Database, _>(Scope::Singleton, |_deps| {
Ok(Database::new(
"postgresql://localhost:5432/mydb".to_string(),
))
})?;
// Register UserService (Singleton)
container.register::<UserService, _>(Scope::Singleton, |deps| {
let db = deps.get::<Database>()?;
Ok(UserService::new(db))
})?;
// Register OrderService (Singleton)
container.register::<OrderService, _>(Scope::Singleton, |deps| {
let db = deps.get::<Database>()?;
let user_service = deps.get::<UserService>()?;
Ok(OrderService::new(db, user_service))
})?;
// Use the container
let order_service = container.get::<OrderService>()?;
order_service.create_order(1, "Laptop");
// Singleton scope reuses instances
let order_service2 = container.get::<OrderService>()?;
assert!(Arc::ptr_eq(&order_service, &order_service2));
Ok(())
}
// Singleton scope - single instance shared across all requests
container.register::<MyService, _>(Scope::Singleton, |deps| {
Ok(MyService::new())
})?;
// Prototype scope - new instance created for each request
container.register::<MyService, _>(Scope::Prototype, |deps| {
Ok(MyService::new())
})?;
// Register multiple beans of the same type with different names
container.register_named::<Database, _>("primary-db", Scope::Singleton, |_deps| {
Ok(Database::new("postgresql://primary:5432/db"))
})?;
container.register_named::<Database, _>("replica-db", Scope::Singleton, |_deps| {
Ok(Database::new("postgresql://replica:5432/db"))
})?;
let service = container.get::<MyService>()?;
let primary_db = container.get_named::<Database>("primary-db")?;
let replica_db = container.get_named::<Database>("replica-db")?;
Dependencies are automatically resolved during bean creation:
container.register::<Database, _>(Scope::Singleton, |_deps| {
Ok(Database::new("postgresql://localhost:5432/mydb"))
})?;
container.register::<UserRepository, _>(Scope::Singleton, |deps| {
let db = deps.get::<Database>()?; // Auto-injected
Ok(UserRepository::new(db))
})?;
container.register::<UserService, _>(Scope::Singleton, |deps| {
let repo = deps.get::<UserRepository>()?; // Auto-injected
Ok(UserService::new(repo))
})?;
The container automatically detects circular dependencies:
// This will fail with a clear error message
container.register::<ServiceA, _>(Scope::Singleton, |deps| {
let b = deps.get::<ServiceB>()?; // ServiceA depends on ServiceB
Ok(ServiceA::new(b))
})?;
container.register::<ServiceB, _>(Scope::Singleton, |deps| {
let a = deps.get::<ServiceA>()?; // ServiceB depends on ServiceA - CIRCULAR!
Ok(ServiceB::new(a))
})?;
// Error: Circular dependency detected! Dependency path: Bean(ServiceA) -> Bean(ServiceB) -> Bean(ServiceA)
BeanContainerThe main container for managing beans.
new() -> Self - Create a new bean containerregister<T, F>(scope: Scope, factory: F) -> Result<(), String> - Register a bean by typeregister_named<T, F>(name: &str, scope: Scope, factory: F) -> Result<(), String> - Register a named beanget<T>() -> Result<Arc<T>, String> - Get a bean by typeget_named<T>(name: &str) -> Result<Arc<T>, String> - Get a bean by namecontains<T>(name: Option<&str>) -> bool - Check if a bean existslen() -> usize - Get the number of registered beansis_empty() -> bool - Check if the container is emptyScopeBean lifecycle scope.
Scope::Singleton - Single instance shared across all requestsScope::Prototype - New instance created for each requestDependenciesProvides access to other beans during bean creation.
get<T>() -> Result<Arc<T>, String> - Get a dependency by typeget_named<T>(name: Option<&str>) -> Result<Arc<T>, String> - Get a dependency by namecurrent_path() -> String - Get the current dependency resolution path (for debugging)See the examples directory for more detailed examples:
Run examples with:
cargo run --example basic
MIT License
Contributions are welcome! Please feel free to submit a Pull Request.