#factory #inject #bean

bean_factory_derive

bean-factory-derive

5个版本

0.1.4 2023年9月25日
0.1.3 2023年9月22日
0.1.2 2023年9月21日
0.1.1 2023年9月21日
0.1.0 2023年9月2日

#5#bean

Download history 83/week @ 2024-04-01 38/week @ 2024-04-08 31/week @ 2024-04-15 13/week @ 2024-04-22 25/week @ 2024-04-29 52/week @ 2024-05-06 19/week @ 2024-05-13 50/week @ 2024-05-20 48/week @ 2024-05-27 19/week @ 2024-06-03 46/week @ 2024-06-10 30/week @ 2024-06-17 23/week @ 2024-06-24 50/week @ 2024-07-01 24/week @ 2024-07-08 15/week @ 2024-07-15

122 每月下载
2 个crate中使用 (通过 bean_factory)

MIT/Apache

11KB
144 代码行

BeanFactory

一个依赖注入容器。

对actix的actor,支持将依赖的对象注入actor对象中。

示例

use std::{collections::HashMap, sync::Arc};

use actix::prelude::*;
use bean_factory::bean;
use bean_factory::BeanDefinition;
use bean_factory::BeanFactory;
use bean_factory::Inject;

#[bean(actor)]
#[derive(Default)]
pub struct ConfigService {
    pub(crate) config_map: HashMap<Arc<String>, Arc<String>>,
}

impl Actor for ConfigService {
    type Context = Context<Self>;
}

#[derive(Debug, Message)]
#[rtype(result = "anyhow::Result<ConfigResult>")]
pub enum ConfigCmd {
    Set(Arc<String>, Arc<String>),
    Query(Arc<String>),
}

pub enum ConfigResult {
    None,
    Value(Arc<String>),
}

impl Handler<ConfigCmd> for ConfigService {
    type Result = anyhow::Result<ConfigResult>;

    fn handle(&mut self, msg: ConfigCmd, _ctx: &mut Self::Context) -> Self::Result {
        match msg {
            ConfigCmd::Set(key, val) => {
                self.config_map.insert(key, val);
                Ok(ConfigResult::None)
            }
            ConfigCmd::Query(key) => {
                if let Some(v) = self.config_map.get(&key) {
                    Ok(ConfigResult::Value(v.clone()))
                } else {
                    Ok(ConfigResult::None)
                }
            }
        }
    }
}

#[bean(inject)]
#[derive(Default)]
pub struct ConfigApi {
    pub(crate) config_service: Option<Addr<ConfigService>>,
}

impl Inject for ConfigApi {
    type Context = Context<Self>;

    fn inject(
        &mut self,
        factory_data: bean_factory::FactoryData,
        _factory: bean_factory::BeanFactory,
        _ctx: &mut Self::Context,
    ) {
        self.config_service = factory_data.get_actor();
        if self.config_service.is_some() {
            println!("ConfigApi:inject success");
        } else {
            println!("ConfigApi:inject none");
        }
        println!("ConfigApi:inject complete");
    }
}

impl Actor for ConfigApi {
    type Context = Context<Self>;
}

impl Handler<ConfigCmd> for ConfigApi {
    type Result = ResponseActFuture<Self, anyhow::Result<ConfigResult>>;

    fn handle(&mut self, msg: ConfigCmd, _ctx: &mut Self::Context) -> Self::Result {
        let config_service = self.config_service.clone();
        let fut = async {
            if let Some(addr) = config_service {
                println!("inject success. use inject config_service handle msg");
                addr.send(msg).await?
            } else {
                Err(anyhow::anyhow!("inject failed. config_service is none"))
            }
        }
        .into_actor(self); //.map(|r,_act,_ctx|{r});
        Box::pin(fut)
    }
}

#[actix::main]
async fn main() -> anyhow::Result<()> {
    std::env::set_var("RUST_LOG","info");
    env_logger::builder().init();
    let factory = BeanFactory::new();
    factory.register(BeanDefinition::actor_with_inject_from_default::<ConfigApi>());
    factory.register(BeanDefinition::actor_from_default::<ConfigService>());
    let _factory_data = factory.init().await;
    let api_addr: Addr<ConfigApi> = factory.get_actor().await.unwrap();
    let key = Arc::new("key".to_owned());
    api_addr.do_send(ConfigCmd::Set(
        key.clone(),
        Arc::new("test value".to_owned()),
    ));
    match api_addr.send(ConfigCmd::Query(key.clone())).await?? {
        ConfigResult::None => println!("not found value"),
        ConfigResult::Value(val) => println!("query value:{}", &val),
    };
    Ok(())
}

依赖

~1.5MB
~35K SLoC