依赖注入

在一个项目中,多个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>

Last updated