And*_*iga 7 factory dependency-injection nestjs
我想在 NestJs 中动态创建类实例,而不是单例。
我找到了两种方法:
import { ChirpSensor } from './chirp-sensor/chirp-sensor';
@Injectable()
export class SensorsService {
registeredSensors: any;
constructor(
@InjectModel('Sensor') private readonly sensorModel: Model<ISensor>,
private i2cService: I2cService) {
const sensors = this.i2cService.getSensors();
sensors.forEach((sensor) => {this.registeredSensors[sensor._id] = new ChirpSensor({name: sensor.name})});
}
Run Code Online (Sandbox Code Playgroud)
我想知道这是否与nest.js的DI方式一致
export const chirpFactory = {
provide: 'CHIRP_SENSOR',
useFactory: (options) => {
console.log('USING FACTORY CHIRP, options', options)
if (process.env.SIMULATION === 'true') {
return new ChirpSensorMock(options);
}
else {
return new ChirpSensor(options);
}
}
};
Run Code Online (Sandbox Code Playgroud)
不太确定如何继续这里/正确注入工厂,因为示例在构造函数中创建对象而没有选项?
NestJs
创建这些类实例的方法是什么?
providers: [
{
provide: 'CHIRP_SENSOR',
useValue: process.env.SIMULATION === 'true'
? ChirpSensorMock
: ChirpSensor
},
],
Run Code Online (Sandbox Code Playgroud)
@Injectable()
export class SensorsService {
registeredSensors: any;
constructor(
@Inject('CHIRP_SENSOR') private ChirpSensorClass: any, // any works but ChirpSensorMock | ChirpSensor not
private i2cService: I2cService
) {
const sensors = this.i2cService.getSensors();
sensors.forEach((sensor) => {this.registeredSensors[sensor._id] = new ChirpSensorClass({name: sensor.name})});
}
Run Code Online (Sandbox Code Playgroud)
您可以通过useValue或useClass通过 DI 将选项传递给您的工厂
providers: [
{
provide: MyOptions,
useValue: options
},
{
provide: 'CHIRP_SENSOR',
useFactory: (options: MyOptions) => {
console.log('USING FACTORY CHIRP, options', options);
if (process.env.SIMULATION === 'true') {
return new ChirpSensorMock(options);
} else {
return new ChirpSensor(options);
}
},
},
],
Run Code Online (Sandbox Code Playgroud)
或者,您也可以完全避免使用工厂,并通过以下方式决定在编译时使用哪个类:
providers: [
{
provide: MyOptions,
useValue: options
},
{
provide: 'CHIRP_SENSOR',
useValue: process.env.SIMULATION === 'true'
? ChirpSensorMock
: ChirpSensor
},
],
Run Code Online (Sandbox Code Playgroud)
或者简单地:
providers: [
{
provide: MyOptions,
useValue: options
},
{
process.env.SIMULATION === 'true' ? ChirpSensorMock : ChirpSensor
},
],
Run Code Online (Sandbox Code Playgroud)
如果您没有如上所述使用工厂,则可以ChirpSensor
使用典型的基于构造函数的依赖项注入将选项注入到您的(或模拟传感器)中:
@Injectable()
export class ChripSensor {
constructor(@inject(MyOptions) private options: MyOptions) {
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
根据您的选项是包装在类中还是简单对象中,您可以使用useValue
或useClass
。您必须useClass
编写更少的代码,并且不必使用@Inject
装饰器,因为类本身用作 DI 令牌。但是,似乎 ifMyOptions
是一个类,您在任何情况下都不需要使用@Inject
来注入依赖项,因为 NestJS 使用该类作为 DI 令牌,无论您是否使用useValue
或useClass
提供依赖项...
归档时间: |
|
查看次数: |
14152 次 |
最近记录: |