gpt4 book ai didi

dependency-injection - 在 nest.js 中实现策略

转载 作者:行者123 更新时间:2023-12-05 03:42:33 27 4
gpt4 key购买 nike

我正在尝试为服务使用策略模式,但是我尝试用作策略上下文的模块似乎只坚持两者之一。这是示例代码:

动物.module.ts

@Module({})
export class AnimalModule {
static register(strategy): DynamicModule {
return {
module: AnimalModule,
providers: [{ provide: 'STRATEGY', useValue: strategy }, AnimalService],
imports: [],
exports: [AnimalService]
};
}
}

动物服务.ts

@Injectable()
export class AnimalService {
constructor (@Inject('STRATEGY') private strategy) {
this.strategy = strategy
}

public makeSound() {
return this.strategy.makeSound()
}
}

猫.module.ts

@Module({
imports: [
AnimalModule.register(catStrategy),
],
controllers: [CatController],
providers: [CatService],
})
export class CatModule {}

猫.服务.ts

@Injectable()
export class CatService {
constructor(
private readonly animalService: AnimalService,
) {}

public makeSound() {
return this.animalService.makeSound()
}
}

狗.module.ts

@Module({
imports: [
AnimalModule.register(dogStrategy),
],
controllers: [DogController],
providers: [DogService],
})
export class DogModule {}

狗.service.ts

@Injectable()
export class DogService {
constructor(
private readonly animalService: AnimalService,
) {}

public makeSound() {
return this.animalService.makeSound()
}
}

猫.strategy.ts

class CatStrategy {
public makeSound() {
return 'meow';
}
}

export const catStrategy = new CatStrategy();

复制问题的 repo :https://github.com/kunukmak/nestjs-strategy-problem-example

澄清一下,在这种情况下,catService.makeSound 和 dogService.makeSound 都会返回“meow”。有可能让狗叫吗?

最佳答案

我认为您正在寻找类似以下内容的内容。查看 repo 以获取完整示例 here .你可以在下面看到,我们正在从 AnimalModule 类中注册一个 DynamicModule:

@Module({
imports: [AnimalModule.register()],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

register() 调用返回的 DynamicModule 负责确定要提供的 AnimalModule 的实现。这意味着我们可以根据环境中的配置自定义 AnimalModule。

@Module({})
export class AnimalModule {
public static register(): DynamicModule {
const AnimalClassProvider = AnimalModule.getClassProvider();
return {
module: AnimalModule,
controllers: [AnimalController],
providers: [AnimalClassProvider],
exports: [AnimalClassProvider],
};
}

private static getClassProvider(): ClassProvider<AnimalService> {
const animalStrategy = process.env.ANIMAL_STRATEGY as AnimalStrategy;
const AnimalServiceClass = AnimalModule.getClassFromStrategy(animalStrategy);
return {
provide: AnimalService,
useClass: AnimalServiceClass,
};
}

private static getClassFromStrategy(strategy: AnimalStrategy): Type<AnimalService> {
switch (strategy) {
case AnimalStrategy.CAT: return CatService;
case AnimalStrategy.DOG: return DogService;
default: return AnimalService;
}
}
}

在这种情况下,AnimalStrategy 只是一个枚举,用于确定我们应该提供哪种服务实现。

通过这种方法,我们允许 Nest 正确构建 Provider 及其所有依赖项。我们只负责告诉 Nest 在遇到 AnimalService 依赖项时将构建哪个实现。这允许我们的应用程序的其余部分不知道实现,只使用我们的 AnimalService 抽象。

来 self 们的 AnimalController:

@Controller('animal')
export class AnimalController {
constructor(private readonly animalService: AnimalService) {}

@Post()
create(@Body() createAnimalDto: CreateAnimalDto) {
return this.animalService.create(createAnimalDto);
}

// ...
}

到我们应用程序中的另一个服务:

@Injectable()
export class PetOwnerService {
constructor(
private readonly animalService: AnimalService,
private readonly petOwnerService: PetOwnerService,
) {}

feedPet(petName: string) {
const petIsHungry = this.petOwnerService.isPetHungry(petName);
if (petIsHungry) this.animalService.feed(petName);
// ...
}
}

关于dependency-injection - 在 nest.js 中实现策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67217819/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com