繁体   English   中英

NestJS - 动态数据访问 Object 服务/提供者

[英]NestJS - Dynamic Data Access Object service/provider

设想

我正在尝试为 API 实现 3 级,controller -> 服务 -> DAO。 因为我不想为每个模块创建实体,所以 DAO 将是动态的。

当前实施

我想在服务中拥有服务/提供者,它将根据我通过的数据库 model 动态实例化。

例如

我可以在 Module1 内拥有 Module1、Module2 等

模块1.controller.ts

import { Controller, Get } from '@nestjs/common';
import { AppService } from './module1.service';

@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}

@Get()
  getHello(): Promise<any> {
    return this.appService.getHello();
 }
}

模块1.service.ts

import { Inject, Injectable, Logger } from '@nestjs/common';

@Injectable()
export class AppService {    
  constructor(
    @Inject('DB_CONNECTION') private db: any
  ) {}

   async getHello(): Promise<any> {
     const dao = this.daoService(this.db.h_users);
     // execute methods of dao and return result
     return ""
    }
  }

模块1.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './module1.controller';
import { AppService } from './module1.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class Module1Module {}

我的数据库模块

数据库.provider.ts

init-models 来自 sequlie-auto

      import { ConfigService } from '@nestjs/config';
      import { Sequelize } from 'sequelize';
      import { initModels } from '../models/init-models';

      export const databaseProviders = [
        {
          inject: [ConfigService],
          provide: 'DATABASE_CONNECTION',
          useFactory: async (config: ConfigService): Promise<Object> => {
            try {
              const sequelize = new Sequelize(
                config.get('DB_NAME') || '',
                config.get('DB_USER') || '',
                config.get('DB_PASS') || '',
                {
                  dialect: config.get('DB_DIALECT') || 'mysql',
                  host: process.env.DB_HOST,
                  port: config.get('DB_PORT') || 3006,
                  define: {
                    timestamps: true,
                  },
                  pool: {
                    max: 5,
                    min: 0,
                    idle: 20000,
                  },
                },
              );
              const db = initModels(sequelize);

              return db;
            } catch (error) {
              throw error;
            }
          },
        },
      ];

现在我有常见的 DAO,它有多种方法,就像 sequelize 方法的包装器

道服务.ts

import { Injectable } from '@nestjs/common';

/**
 * Class reperesnt the Generic Data Acceess Object
 */
@Injectable()
export class DAOService {
  /**
   * @param {string} model - sequalize model
   */
  declare model;
  constructor(model: any) {
    this.model = model;
  }

  /**
   * Get a single record for specified model by unique idenntifier
   */
  getRecordById = async (id: number) => {
    try {
      if (id) {
        const record = await this.model.findOne({ where: { id: id } });
        if (record !== null) {
          return { success: true, data: record };
        }
      } else {
        return { success: false };
      }
      return { success: false };
    } catch (e) {
      throw e;
    }
  };
}

数据库.module.ts

import { Global, Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { databaseProviders } from './database.provider';
import { databaseProvider2 } from './database.provider2';

@Global()
@Module({
  imports: [ConfigModule],
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}

问题

我无法弄清楚如何准确地前进,我试图注入 DAOService 但它给出了错误。

如果我做

数据库.module.ts

import { Global, Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { DAOService } from './dao.service';
import { databaseProviders } from './database.provider';

@Global()
@Module({
  imports: [ConfigModule],
  providers: [...databaseProviders, DAOService],
  exports: [...databaseProviders, DAOService],
})
export class DatabaseModule {}

并尝试在 Module1 服务中注入和使用,我不能随意使用它

import { Inject, Injectable, Logger } from '@nestjs/common';
import { DAOService } from '../database/dao.service';

@Injectable()
export class AppService {
  // private daoService: DAO;
  constructor(
    @Inject('DB_CONNECTION') private db: any,
    private daoService: DAOService,
  ) {}

  async getHello(): Promise<any> {
    const r = this.daoService(this.db.h_users);
    // const r = await this.daoService.getAllRecords(1, 10, 1, 'DESC', '', {});
    // Logger.log(JSON.stringify(r, null, 2));
    return r;
  }
}

错误

src/Module1/module1.service.ts:13:26 - error TS2349: This expression is not callable.
Type 'DAOService' has no call signatures.

目标

我唯一的目标是根据我传递的数据库 model 实例化或动态 DAO 并在服务中使用它,如果可能的话,如果我想扩展某些模块的功能,我希望扩展 DAOService。

我是 NestJS 的新手,但这就是我在另一个服务中使用服务的方式,也许它可以提供帮助

 @Injectable() export class Service1 { constructor( private DAOService: DAO ) { this.DAOService.init(); } async myMethod(data: any): Promise<any> { await this.DAOService.myDAOFunction(/* param */); } } /* DAO Service */ @Injectable({ scope: Scope.TRANSIENT }) export default class DAO { private obj; init() { this.obj = new DAO(); } async myDAOFunction(/* param */){ } }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM