NestJs:动态创建 Class 的实例
NestJs: Dynamically Create Instances of Class
我想在 NestJs 中动态创建 class 个实例,而不是单例。
我找到了两种方法:
1) 直接创建class(ChripSensor 不是@Injectable)
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})});
}
我想知道这是否符合nest.js
的DI方式
2) 第二种解决方案是通过 factory,但这里我不知道如何传递选项。
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);
}
}
};
不太确定如何在此处继续/正确注入工厂,因为示例在没有选项的情况下在构造函数中创建对象?
问题:
创建那些 class 个实例的 NestJs
方法是什么?
编辑 - B12Toastr
模块 - 在编译时获取 Mock 或 Original
providers: [
{
provide: 'CHIRP_SENSOR',
useValue: process.env.SIMULATION === 'true'
? ChirpSensorMock
: ChirpSensor
},
],
传感器服务
@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})});
}
您可以通过 DI 通过 useValue or useClass
将选项传递给您的工厂
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);
}
},
},
],
或者,您也可以完全避免使用工厂,并通过 class 在编译时决定使用哪个工厂:
providers: [
{
provide: MyOptions,
useValue: options
},
{
provide: 'CHIRP_SENSOR',
useValue: process.env.SIMULATION === 'true'
? ChirpSensorMock
: ChirpSensor
},
],
或者简单地说:
providers: [
{
provide: MyOptions,
useValue: options
},
{
process.env.SIMULATION === 'true' ? ChirpSensorMock : ChirpSensor
},
],
如果您没有使用上述工厂,则可以使用典型的基于构造函数的依赖注入将选项注入 ChirpSensor
(或模拟传感器):
@Injectable()
export class ChripSensor {
constructor(@inject(MyOptions) private options: MyOptions) {
}
// ...
}
根据您的选项是包裹在 class 还是简单的对象中,您可以使用 useValue
或 useClass
。使用 useClass
您必须编写更少的代码并且不必使用 @Inject
装饰器,因为 class 本身用作 DI 令牌。但是,如果 MyOptions
是 class,您似乎在任何情况下都不需要使用 @Inject
来注入依赖项,因为 NestJS 使用 class 作为 DI 令牌,无论您是否使用 useValue
或 useClass
来提供依赖...
我想在 NestJs 中动态创建 class 个实例,而不是单例。
我找到了两种方法:
1) 直接创建class(ChripSensor 不是@Injectable)
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})});
}
我想知道这是否符合nest.js
的DI方式2) 第二种解决方案是通过 factory,但这里我不知道如何传递选项。
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);
}
}
};
不太确定如何在此处继续/正确注入工厂,因为示例在没有选项的情况下在构造函数中创建对象?
问题:
创建那些 class 个实例的 NestJs
方法是什么?
编辑 - B12Toastr
模块 - 在编译时获取 Mock 或 Original
providers: [
{
provide: 'CHIRP_SENSOR',
useValue: process.env.SIMULATION === 'true'
? ChirpSensorMock
: ChirpSensor
},
],
传感器服务
@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})});
}
您可以通过 DI 通过 useValue or useClass
将选项传递给您的工厂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);
}
},
},
],
或者,您也可以完全避免使用工厂,并通过 class 在编译时决定使用哪个工厂:
providers: [
{
provide: MyOptions,
useValue: options
},
{
provide: 'CHIRP_SENSOR',
useValue: process.env.SIMULATION === 'true'
? ChirpSensorMock
: ChirpSensor
},
],
或者简单地说:
providers: [
{
provide: MyOptions,
useValue: options
},
{
process.env.SIMULATION === 'true' ? ChirpSensorMock : ChirpSensor
},
],
如果您没有使用上述工厂,则可以使用典型的基于构造函数的依赖注入将选项注入 ChirpSensor
(或模拟传感器):
@Injectable()
export class ChripSensor {
constructor(@inject(MyOptions) private options: MyOptions) {
}
// ...
}
根据您的选项是包裹在 class 还是简单的对象中,您可以使用 useValue
或 useClass
。使用 useClass
您必须编写更少的代码并且不必使用 @Inject
装饰器,因为 class 本身用作 DI 令牌。但是,如果 MyOptions
是 class,您似乎在任何情况下都不需要使用 @Inject
来注入依赖项,因为 NestJS 使用 class 作为 DI 令牌,无论您是否使用 useValue
或 useClass
来提供依赖...