在nest.js中实施策略 [英] Implementing strategy in nest.js

查看:30
本文介绍了在nest.js中实施策略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将策略模式用于服务,但是我尝试用作策略上下文的模块似乎只坚持这两种模式中的一种。以下是示例代码:

Animal.Mode.ts

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

Animal.service.ts

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

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

cat.module e.ts

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

cat.service.ts

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

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

dog.module e.ts

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

dog.service.ts

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

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

cat.Strategy y.ts

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

export const catStrategy = new CatStrategy();

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

为了清楚起见,在本例中,catService.makeSound和dogService.makeSound都返回了喵";。能让狗吠吗?

推荐答案

我认为您正在寻找类似以下内容的内容。有关完整示例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正确地构造提供程序及其所有依赖项。我们只负责在Nest遇到AnimalService依赖项时告诉它将构造哪个实现。这允许我们应用程序的睡觉不知道实现,而只使用我们的AnimalService抽象。

来自我们的动物控制器:

@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);
        // ... 
    }
}

这篇关于在nest.js中实施策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆