16 个版本 (7 个重大变更)
0.8.3 | 2024 年 3 月 26 日 |
---|---|
0.8.1 | 2024 年 2 月 26 日 |
0.7.0 | 2023 年 12 月 6 日 |
0.6.0 | 2023 年 9 月 11 日 |
#292 在 Rust 模式
每月 99 次下载
用于 2 crates
145KB
2K SLoC
鲁迪
英文 | 简体中文
鲁迪 - Rust 的开箱即用的依赖注入框架。
use rudi::{Context, Singleton, Transient};
// Register `fn(cx) -> A { A }` as the constructor for `A`
#[derive(Debug)]
#[Transient]
struct A;
#[derive(Debug)]
struct B(A);
// Register `fn(cx) -> B { B::new(cx.resolve::<A>()) }` as the constructor for `B`
#[Transient]
impl B {
#[di]
fn new(a: A) -> B {
B(a)
}
}
// Register `fn(cx) -> C { C::B(cx.resolve::<B>()) }` as the constructor for `C`
#[allow(dead_code)]
#[Transient]
enum C {
A(A),
#[di]
B(B),
}
// Register `fn(cx) -> () { Run(cx.resolve::<B>(), cx.resolve::<C>()) }` as the constructor for `()`
#[Singleton]
fn Run(b: B, c: C) {
println!("{:?}", b);
assert!(matches!(c, C::B(_)));
}
fn main() {
// Automatically register all types and functions with the `#[Singleton]`, `#[Transient]` or `#[SingleOwner]` attribute.
let mut cx = Context::auto_register();
// Get an instance of `()` from the `Context`, which will call the `Run` function.
// This is equivalent to `cx.resolve::<()>();`
cx.resolve()
}
功能
- 三个作用域:
Singleton
、Transient
和SingleOwner
(示例)。 - 异步函数和异步构造函数。
- 可以在
struct
、enum
、impl block
和function
上使用属性宏。 - 手动和自动注册(感谢 inventory)。
- 轻松绑定特质的实现和特质的对象。
- 通过类型和名称区分不同的实例。
- 泛型(但必须是单态化并手动注册)(示例)。
- 条件注册 (示例)。
- 引用(仅限
Singleton
和SingleOwner
作用域)(示例)。
更复杂的示例
use std::{fmt::Debug, rc::Rc};
use rudi::{Context, Singleton, Transient};
// Register `async fn(cx) -> i32 { 42 }` as the constructor for `i32`,
// and specify the name of the instance of this `i32` type as `"number"`.
#[Singleton(name = "number")]
async fn Number() -> i32 {
42
}
// Register `async fn(cx) -> Foo { Foo { number: cx.resolve_with_name_async("number").await } }`
// as the constructor for `Foo`, and specify the name of the instance of this `Foo` type as `"foo"`.
#[derive(Debug, Clone)]
#[Singleton(async, name = "foo")]
struct Foo {
#[di(name = "number")]
number: i32,
}
#[derive(Debug)]
struct Bar(Foo);
impl Bar {
fn into_debug(self) -> Rc<dyn Debug> {
Rc::new(self)
}
}
// Register `async fn(cx) -> Bar { Bar::new(cx.resolve_with_name_async("foo").await).await }`
// as the constructor for `Bar`.
//
// Bind the implementation of the `Debug` trait and the trait object of the `Debug` trait,
// it will register `asycn fn(cx) -> Rc<dyn Debug> { Bar::into_debug(cx.resolve_async().await) }`
// as the constructor for `Rc<dyn Debug>`.
#[Transient(binds = [Self::into_debug])]
impl Bar {
#[di]
async fn new(#[di(name = "foo")] f: Foo) -> Bar {
Bar(f)
}
}
#[Singleton]
async fn Run(bar: Bar, debug: Rc<dyn Debug>, #[di(name = "foo")] f: Foo) {
println!("{:?}", bar);
assert_eq!(format!("{:?}", bar), format!("{:?}", debug));
assert_eq!(format!("{:?}", bar.0.number), format!("{:?}", f.number));
}
#[tokio::main]
async fn main() {
let mut cx = Context::auto_register();
cx.resolve_async().await
}
致谢
贡献
感谢您帮助改进项目!我们非常高兴有您加入!
许可证
许可协议为以下之一:
- Apache License, Version 2.0,(LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT 许可协议(LICENSE-MIT 或 http://opensource.org/licenses/MIT)任选其一。
贡献
除非您明确声明,否则根据 Apache-2.0 许可证定义的,您有意提交以包含在作品中的任何贡献,都将按照上述方式双重许可,无需附加任何条款或条件。
依赖项
~0.4–1MB
~21K SLoC