#atom #scope #context #framework #cdi

natom

适用于Rust的最小CDI框架

3个版本

使用旧的Rust 2015

0.1.1-rc.22023年6月29日
0.1.0 2023年6月28日

#atom中排名第40

MIT许可证

12KB
125

Natom

crates.io version crates.io downloads

Natom是Rust中的最小CDI实现。


lib.rs:

这个包是一个为Rust提供的最小CDI实现。虽然CDI实现并不完全符合标准,但它与WELD有一些相似之处。

CDI简介

CDI是一个广泛的话题,不容易全面涵盖。

原子

原子(或WELD中的bean)是CDI系统的基石。原子简单地是一个受管理的结构体;受管理的意思是构建和销毁由上下文处理。在一个大型应用程序中,您可能有多个需要传递和注入的应用程序范围内的对象(实际上意味着在某个构造函数中使用)。这可能会变得非常繁琐。原子既适合(单例)应用程序范围内的对象,也适合创建新实例。

原子通过在结构体上注释macro@atom来创建。

#[atom]
struct Foo {}

上下文

原子是在上下文中创建的。

作用域

每个原子都有一个指定的作用域。作用域指的是原子的构建和重用方式。注入的行为取决于原子的作用域。以下实现了以下作用域:

  • 入口点
  • 单例
  • 依赖

关系 & 注入

当构建面向服务的系统时,可能会将逻辑拆分为许多不同的对象,每个对象都与另一个对象有关,同时本身也是一个逻辑单元。因此,我们需要一种表示关系的方法。

#[atom]
struct FooService {
    #[inject]
    repository: FooRepository,
}

#[atom]
struct FooRepository {}

注入

通过使用macro@inject宏,我们可以将实例注入到我们的构造函数中。这个实例可以共享于不同的FooService实例之间,或者根据FooRepository的作用域是独特还是共享。

生产

有时,我们希望注入的不是原子。这可能包括第三方依赖项,或者是随机数。

#[atom]
struct IntProducer {
    
}

impl IntProducer {
    #[produces]
    fn make_int() i32 {
        0
    }
}

#[atom]
struct Foo {
    #[inject]
    number: i32,
}

我们还想能够命名生产者的替代品。

生命周期管理

有时,注入所有依赖项或仅移除对象并不足以管理持久性(例如文件、套接字)。在这种情况下,我们可以使用自定义函数中的功能,例如在macro@constructmacro@destruct中指定行为。

内建原子

尽管核心CDI实现很有用,但还有一些与整个生态系统相关的相关部分。

对于配置,我们使用一种称为配置属性的东西。带有 [@config_property] 注解的字段会自动标记为 [@inject]。 [@config_property] 在注入时接受一个配置属性的名称,并在运行时查找该属性。该属性可以有默认值,并可以从 ENV 中加载。

#[atom]
struct Foo {
    #[config_property(foo.speed)]
    speed: f32,
}

[@config_property] 接受的类型包括:

  • 字符串
  • 整数 ([i8], [i16], [u8], [u16], ...)
  • 浮点数 ([f32], [f64])

调度

对于调度任务...

示例应用

#[atom]
struct Foo {
}

#[atom]
struct Bar {

}

define_base_atoms!();

fn main() {
    let context = Context::new(BaseAtomRegistry {});
    context.start();
}

依赖项

~280–730KB
~18K SLoC