简体   繁体   English

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

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

Scenario设想

I'm trying to implement 3 level for APIs, controller -> Service -> DAO.我正在尝试为 API 实现 3 级,controller -> 服务 -> DAO。 As I don't want to create entity per module, and DAO will be dynamic.因为我不想为每个模块创建实体,所以 DAO 将是动态的。

Current Implementation当前实施

I want to have service/provider inside service which will dynamically instantiate based on which database model I pass.我想在服务中拥有服务/提供者,它将根据我通过的数据库 model 动态实例化。

eg例如

I can have Module1, Module2 etc. Inside Module1我可以在 Module1 内拥有 Module1、Module2 等

module1.controller.ts模块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();
 }
}

module1.service.ts模块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 ""
    }
  }

module1.module.ts模块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 {}

My DatabaseModule我的数据库模块

database.provider.ts数据库.provider.ts

init-models is from sequelie-auto 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;
            }
          },
        },
      ];

Now I've common DAO which have multiple method which is like wrapper on sequelize methods现在我有常见的 DAO,它有多种方法,就像 sequelize 方法的包装器

dao.service.ts道服务.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;
    }
  };
}

database.module.ts数据库.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 {}

Issue问题

I'm not able to figure out how to exactly move forward, I've tried to inject DAOService but it gives error.我无法弄清楚如何准确地前进,我试图注入 DAOService 但它给出了错误。

If I do如果我做

database.module.ts数据库.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 {}

And try to inject and use inside Module1 service, I can't use it as I want to并尝试在 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;
  }
}

Error错误

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

Goal目标

My only goal is to have instantiate or have dynamic DAO based on which database model I pass and use it inside service and if possible I want to have DAOService extended if for some module I want to extend the functionality.我唯一的目标是根据我传递的数据库 model 实例化或动态 DAO 并在服务中使用它,如果可能的话,如果我想扩展某些模块的功能,我希望扩展 DAOService。

I'm new to NestJS, but this is how I use a service inside another, maybe it can help我是 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.

相关问题 有条件地将服务类实例化为 NestJS 中的提供者 - Conditionally instantiate service class as a provider in NestJS 在 controller 测试期间,Nestjs 注入的提供程序服务未定义 - Nestjs injected provider service is undefined during controller tests Nestjs 日志响应数据 object - Nestjs log response data object 如何使用 JSON 中的数据初始化多个 nestjs 提供程序? - How can I initialize multiple nestjs provider with data from JSON? 动态数据提供程序中没有数据的amcharts - amcharts that have no data in dynamic data provider 使用服务提供程序(打字稿/角度 2)在 ionic 2 视图中恢复和显示 json 数据(对象、数组) - recover and display json data (Object, array) in ionic 2 view using service provider (typescript/angular 2) 动态访问对象名称 - Dynamic access to the object name 我可以从数据库提供程序外部访问 sequelize,使用 sequelize 在nestjs 中编写原始查询吗 - can i access sequelize from outside the database provider writing raw query in nestjs using sequelize NestJS:拦截器测试中不允许通过字符串文字访问 object - NestJS: object access via string literals is disallowed in an interceptor test 将 TypeORM 存储库注入 NestJS 服务以进行模拟数据测试 - Inject TypeORM repository into NestJS service for mock data testing
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM