首页 > 数据库 > 数据库开发技术 > 【每周一库】- shaku - 依赖注入/容器库
Rust中辅助依赖注入的库。shaku_rocket).provider模块,以了解如何创建寿命较短的服务。Arc作为依赖项。use std::sync::Arc;
trait IOutput {
fn write(&self, content: String);
}
trait IDateWriter {
fn write_date(&self);
}
struct ConsoleOutput;
impl IOutput for ConsoleOutput {
fn write(&self, content: String) {
println!("{}", content);
}
}
struct TodayWriter {
output: Arc<dyn IOutput>,
today: String,
year: usize,
}
impl IDateWriter for TodayWriter {
fn write_date(&self) {
self.output.write(format!("Today is {}, {}", self.today, self.year));
}
}
thread_safe功能时,必须使用 static和 Send + Sync。Interface 特征可作为这些界限的特征别名,并会自动实现那些实现了界限的类型。use shaku::Interface;
trait IOutput: Interface {
fn write(&self, content: String);
}
trait IDateWriter: Interface {
fn write_date(&self);
}
TodayWriter 类型为 IDateWriterConsoleOutput 类型为 IOutputComponent, 既可以手动实现或者使用派生宏实现:use shaku::Component;
#[derive(Component)]
#[shaku(interface = IOutput)]
struct ConsoleOutput;
TodayWriter 依赖于 IOutput 组件。Arc中的特征对象。然后(如果使用派生宏的方式)在该属性上使用#[shaku(inject)]声明告知shaku来注入依赖项。use shaku::Component;
#[derive(Component)]
#[shaku(interface = IDateWriter)]
struct TodayWriter {
#[shaku(inject)]
output: Arc<dyn IOutput>,
today: String,
year: usize,
}
Component::dependencies里返回Dependency对象并且将它们通过Component::build进行手动注入。ContainerBuilder并用它注册所有组件。它会生成一个可以用来解析组件的Container。use shaku::ContainerBuilder;
let mut builder = ContainerBuilder::new();
builder.register_type::<ConsoleOutput>();
let container = builder.build().unwrap();
ContainerBuilder注册一个组件来完成。with_named_parameter和with_typed_parameter来传参:builder
.register_type::<TodayWriter>()
.with_named_parameter("today", "Jan 26".to_string())
.with_typed_parameter::<usize>(2020);
Container中使用其中的某一个resolve方法来完成。let writer: &dyn IDateWriter = container.resolve_ref().unwrap();
writer.write_date();
ContainerBuilder中。resolve_ref()方法会向Container询问一个实现了IDateWriter接口的实例。Container将会查找对应IDateWriter接口的实现是TodayWriter,并返回该组件的实例。IOutput 并且在程序运行起始注册组件的地方做出相应的调整使用新完成的实现。这样就可以避免修改其他地方的代码。这就是所谓的控制反转!use shaku::{Component, ContainerBuilder, Interface};
use std::sync::Arc;
trait IOutput: Interface {
fn write(&self, content: String);
}
trait IDateWriter: Interface {
fn write_date(&self);
}
#[derive(Component)]
#[shaku(interface = IOutput)]
struct ConsoleOutput;
impl IOutput for ConsoleOutput {
fn write(&self, content: String) {
println!("{}", content);
}
}
#[derive(Component)]
#[shaku(interface = IDateWriter)]
struct TodayWriter {
#[shaku(inject)]
output: Arc<dyn IOutput>,
today: String,
year: usize,
}
impl IDateWriter for TodayWriter {
fn write_date(&self) {
self.output.write(format!("Today is {}, {}", self.today, self.year));
}
}
let mut builder = ContainerBuilder::new();
builder.register_type::<ConsoleOutput>();
builder
.register_type::<TodayWriter>()
.with_named_parameter("today", "Jan 26".to_string())
.with_typed_parameter::<usize>(2020);
let container = builder.build().unwrap();
let writer: &dyn IDateWriter = container.resolve_ref().unwrap();
writer.write_date();
原文作者:Rust语言中文社区;如有侵权,请联系管理员删除。