4个版本

0.3.9 2024年7月25日
0.3.8 2024年2月21日
0.3.7 2024年1月8日
0.3.6 2023年12月23日
0.2.7 2023年6月22日

#372 in 网页编程

Download history 1/week @ 2024-05-28 4/week @ 2024-06-04 126/week @ 2024-07-23 11/week @ 2024-07-30

每月137次下载
用于 fama

MIT许可证

44KB
844

Busybody

Busybody 是 Rust 应用的服务容器和依赖注入器。

Busybody 作为服务容器

服务容器示例
use busybody::*;

#[derive(Debug)]
struct Config {
  hostname: String
}

fn main() {
  let container = ServiceContainerBuilder::new()
  .service(Config{ hostname: "https://127.0.0.1".into() }) // Will be wrapped in Service<T> ie: Arc<T>
  .register(600i32) // left as it is, i32
  .build();

  let config = container.get::<Config>().unwrap(); // When "some", will return Service<Config>
  let max_connection = container.get_type::<i32>().unwrap(); // When "some", will return i32

  println!("config: {:#?}", &config);
  println!("hostname: {:#?}", &config.hostname);
  println!("max connection: {}", max_connection);
}

Busybody 作为依赖注入器

依赖注入示例
use busybody::*;

#[derive(Debug)]
struct Config {
  hostname: String
}

#[busybody::async_trait]
impl busybody::Injectable for Config { // implementing "Injectable" makes your type callable by the injector 

    async fn inject(_: &ServiceContainer) -> Self {
       Self {
           hostname: "localhost".into()
       }
    }
}


#[tokio::main]
async fn main() {
  let config = helpers::provide::<Config>().await;

  println!("config: {:#?}", &config);
  println!("hostname: {:#?}", &config.hostname);
}
依赖注入:单例示例
use busybody::*;

#[derive(Debug)]
struct Config {
  hostname: String
}

#[busybody::async_trait]
impl busybody::Injectable for Config { // implementing "Injectable" makes your type injectable by the injector

    async fn inject(_: &ServiceContainer) -> Self {
       Self {
           hostname: "localhost".into()
       }
    }
}


#[tokio::main]
async fn main() {
  let config = helpers::singleton::<Config>().await;

  println!("config: {:#?}", &config);
  println!("hostname: {:#?}", &config.hostname);
}
依赖注入:通过传递所有必要参数调用函数/closure
use busybody::{helpers, RawType, Service, ServiceContainerBuilder};

#[tokio::main]
async fn main() {
    // 1. Setup the container
    _ = ServiceContainerBuilder::new()
        .register(200) // Register an i32 value that is not wrapped in Service<T>
        .service(400) // Register an i32 value that is wrapped in Service<T>
        .build();

    // 2. `inject_and_call` calls the provided function/closure, injecting all of it's required parameters
    //     inject_and_call takes a function/closure that expects 0 to 17 arguments
    //     The function **must** be async
    let double_result = helpers::inject_and_call(double).await;
    println!("200 double is: {}", double_result);

    // 3. Same as above but we are making use of "RawType<T>"
    //    RawType<T> tries to find an instance of the specified type. If none exist,
    //    it uses the `default` associate method to create a default instance of the Type.
    //    This means, the "T" in RawType must implement the `Default` trait.
    let sum = helpers::inject_and_call(|raw_i32: RawType<i32>, service_i32: Service<i32>| async {
        raw_i32.into_inner() + *service_i32.into_inner()
    })
    .await;
    println!("Service<200> + RawType<400> = {}", sum);
}

// 4. Function is taken an I32.
async fn double(count: i32) -> i32 {
    count * 2
}

示例

示例文件夹 examples 包含简单和完整示例。如果示例都没有帮助,请提供您的用例,我会尝试提供一个。

反馈

如果您觉得这个crate很有用,请星标仓库。同时提交您的问题和建议。

许可证

MIT许可证 (MIT)

特此授予任何人无限制地使用本软件及其相关文档文件(“软件”)的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本的权利,以及允许向软件提供方提供软件的人士进行上述操作,但需遵守以下条件

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

本软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、特定用途的适用性和非侵权性。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任负责,无论此类责任源于合同、侵权或其他方式,无论此类责任是否源于、与软件或软件的使用或其它方式相关。

依赖关系

~0.9–1.5MB
~32K SLoC