在一个项目中,多个BLoC之前并不是完全孤立的,他们往往是相互依赖的,例如评论模块可能依赖了帖子模块和账户模块,同时帖子模块自己也依赖了账户模块。如果我们需要手动地去维护这些BLoC实例之间的联系的话,将无比的繁琐和低效。
在jorum,我们可以在BLoC的构造函数中使用@inject
修饰器来实现自动的依赖注入:
@bloc
export class FooBloc {
//...
}
@bloc
export class BarBloc {
constructor(
@inject public fooBloc: FooBloc
) {}
//...
}
这样,jorum就会在创建BarBloc
的时候,找到Context树上最近的FooBloc
的实例,并将其作为参数传给BarBloc
的构造函数。
也就是说,虽然是有依赖注入器,但是,我们仍然需要在上级组件树中先使用Provider
提供一个FooBloc
:
<Provider of={FooBloc}>
<Provider of={BarBloc}>
{/*...*/}
</Provider>
</Provider>
但是注入也可以是可选的,我们只需要把构造函数对应的参数标记为可选即可:
@bloc
export class BarBloc {
constructor(
@inject public fooBloc?: FooBloc //注意我们在fooBloc参数的后面加上了一个optional标记
) {}
//...
}
这样,jorum会尝试获取一个FooBloc
的实例,但是如果拿不到的话,就会把null
作为fooBloc
参数。
<Provider of={BarBloc}>
{/* 在这里barBloc.fooBloc是null */}
</Provider>
<Provider of={FooBloc}>
<Provider of={BarBloc}>
{/* 在这里barBloc.fooBloc是一个正常的实例 */}
</Provider>
</Provider>
如果我们想同时给BarBloc
的构造函数设置一些额外的自定义的参数,那么我们需要把注入型参数(也就是@inject
修饰的参数)放到最后面:
@bloc
export class BarBloc {
constructor(
public a: string,
b: string,
@inject public fooBloc: FooBloc,
) {}
//...
}
然后在使用Provider
提供BarBloc
的时候,忽略注入型参数即可:
<Provider of={BarBloc} args={['A', 'B']}></Provider>