#injection #di #spring #ioc #dependency-injection

springtime-di

基于自动组件发现和运行时自动装配的依赖注入框架

8个版本 (3个稳定版)

1.0.2 2024年5月7日
1.0.1 2023年11月27日
1.0.0 2023年4月26日
0.3.2 2023年4月20日
0.2.1 2023年4月7日

#418 in 异步

Download history 7/week @ 2024-04-22 147/week @ 2024-05-06 6/week @ 2024-05-13 17/week @ 2024-05-20 16/week @ 2024-05-27 5/week @ 2024-06-03 10/week @ 2024-06-10 33/week @ 2024-06-17 14/week @ 2024-06-24 13/week @ 2024-07-08 6/week @ 2024-07-15 49/week @ 2024-07-29 9/week @ 2024-08-05

每月65次下载
用于 3 crates

MIT 许可证

115KB
2.5K SLoC

Springtime 依赖注入

crates.io version build status

受 Java 中的 Spring 框架启发的依赖注入 crate。

Springtime 的理念是提供简单依赖注入的手段,无需不必要的手动配置,例如,无需显式创建依赖并将其存储在容器中。核心概念是 Component - 可以由框架创建、注入和管理的东西。将尽可能多的工作放在编译时元数据创建和自动组件发现上,从而使用户能够专注于组件的 使用,而不是其 创建管理。强调属性,使依赖配置成为声明性的(我想完成什么),将细节留给框架本身(如何完成所请求的任务)。

功能

  • 具体和特质对象注入
  • 自动和手动注册支持
  • 组件过滤
  • 条件组件注册
  • 组件优先级
  • 自定义构造函数
  • 按字段配置初始化
  • 可定制实例作用域
  • 异步 + 同步支持(运行时无关)

基本用法

Springtime 可以高度配置,但最基本的使用示例非常简单,只需使用几个属性即可完全配置依赖链。有关 教程、高级功能和模式,请参阅 示例,它们构成一个逐步指南。

use springtime_di::factory::ComponentFactoryBuilder;
use springtime_di::instance_provider::{ComponentInstancePtr, TypedComponentInstanceProvider};
use springtime_di::{component_alias, injectable, Component};

// this is a trait we would like to use in our component
#[injectable]
trait TestTrait {
    fn foo(&self);
}

// this is a dependency which implements the above trait and also is an injectable component
#[derive(Component)]
struct TestDependency;

// we're telling the framework to provide TestDependency when asked for dyn TestTrait
#[component_alias]
impl TestTrait for TestDependency {
    fn foo(&self) {
        println!("Hello world!");
    }
}

// this is another component, but with a dependency
#[derive(Component)]
struct TestComponent {
    // the framework will know how to inject dyn TestTrait, when asked for TestComponent (Send + Sync are only needed
    // with the "threadsafe" feature)
    // more details are available in the documentation
    dependency: ComponentInstancePtr<dyn TestTrait + Send + Sync>,
    // alternatively, you can inject the concrete type
    // dependency: ComponentInstancePtr<TestDependency>,
}

impl TestComponent {
    fn call_foo(&self) {
        self.dependency.foo();
    }
}

// note: for the sake of simplicity, errors are unwrapped, rather than gracefully handled
fn main() {
    // components are created by a ComponentFactory
    // for convenience, ComponentFactoryBuilder can be used to create the factory with a reasonable
    // default configuration
    let mut component_factory = ComponentFactoryBuilder::new()
        .expect("error initializing ComponentFactoryBuilder")
        .build();

    let component = component_factory
        .primary_instance_typed::<TestComponent>()
        .expect("error creating TestComponent");

    // prints "Hello world!"
    component.call_foo();
}

依赖项

~1.1–2MB
~38K SLoC