为什么模型具有存储库模式的未定义状态?
Why model has undefined state with repository pattern?
我正在尝试将存储库模式与 TypeScript 结合使用
现在我有 base.repository
实现了我需要的所有功能,我将其设为通用类型,我想在将模型注入 constructor
时传递模型,但出于某种原因,在传递值时,我有特定模型的未定义状态,我做错了什么?
在 console.log()
中显示模型未定义,而在文件 register.service.ts
中显示模型也未定义,但我将其作为通用传递。
register.service.ts
import { BaseRepository } from "../repositories/base.repository";
import { Creator } from '../data/models/Creator'
import { RegisterDto } from "../types/dtos/register.dto";
import { Injectable } from '@nestjs/common'
import { RegisterMapper } from '../mappers/register.mapper'
import { errors } from '../errors'
import { mailer } from '../utils/nodemailer'
@Injectable()
export class RegisterService {
constructor(
private readonly repository: BaseRepository<Creator>,
private readonly mapper: RegisterMapper
) { }
async createAccount (doc: RegisterDto) {
const emailExist = await this.existByEmail(doc.email)
if (emailExist) {
return errors.EMAIL_EXIST()
}
const created = await this.repository.create(this.mapper.toDomain(doc))
await mailer(doc.email)
return created
}
private async existByEmail(email: string): Promise<boolean> {
console.log(email)
console.log(this.repository)
const response = await this.repository.get({ email })
return !!response.email;
}
}
base.repository.ts
import { ModelType } from '@typegoose/typegoose/lib/types'
import { DuplicateKeyError } from '../errors/DuplicateKeyError'
import { DocumentNotFoundError } from '../errors/DocumentNotFoundError'
import { Model } from 'mongoose'
import { Inject, Injectable, Optional } from '@nestjs/common'
@Injectable()
export class BaseRepository<T = any> {
constructor(
@Optional() @Inject('MODEL') private Model: any
) { }
async create (object): Promise<T> {
const Model = this.Model
console.log(Model)
const uniqueKey = Model.getUniqueKey ? Model.getUniqueKey() : null
if (uniqueKey && object[uniqueKey]) {
const criteria = {
[uniqueKey]: object[uniqueKey]
}
const existing = await Model.findOne(criteria)
if (existing) {
throw new DuplicateKeyError(Model, criteria)
}
}
const model = new Model(object)
return model.save()
}
async update (criteria, object, options = {}) {
const Model = this.Model
const uniqueKey = Model.getUniqueKey ? Model.getUniqueKey() : '_id'
const data = { ...object }
delete data[uniqueKey]
delete data.createdAt
return this.updateRaw(criteria, { $set: { ...data } }, options)
}
async updateRaw (criteria, data, options = {}) {
const query = this._getDbQuery(criteria, options)
const result = await this.Model.findOneAndUpdate(query, data, { new: true, ...options })
if (!result) {
throw new DocumentNotFoundError(this.Model, query)
}
return result
}
async save (modelInstance) {
return modelInstance.save()
}
async get (criteria, options: any = {}): Promise<T | undefined> {
console.log(Model)
const promise = await this.Model.findOne(this._getDbQuery(criteria, options)).exec()
if (options.select) {
promise.select(options.select)
}
return promise
}
async find (criteria, options): Promise<ReturnType<ModelType<T>['find']>> {
return this.Model.find(this._getDbQuery(criteria, options))
}
async resolve (criteria): Promise<T> {
return this.Model.resolve(this._getDbQuery(criteria))
}
async count (query) {
return this.Model.countDocuments(this._getDbQuery(query))
}
async delete (criteria) {
return this.Model.remove(this._getDbQuery(criteria))
}
_getDbQuery (criteria, options: any = {}) {
if ('getDbQuery' in criteria) {
const dbQuery = criteria.getDbQuery(options)
return 'find' in dbQuery
? dbQuery.find
: dbQuery
} else {
return criteria
}
}
}
我应该怎么做才能获得此存储库中的实际模型?
我在存储库注入之前在每个服务中添加了注入令牌
现在代码如下所示
import { BaseRepository } from "../repositories/base.repository";
import { Creator } from '../data/models/Creator'
import { RegisterDto } from "../types/dtos/register.dto";
import { Injectable } from '@nestjs/common'
import { RegisterMapper } from '../mappers/register.mapper'
import { errors } from '../errors'
import { mailer } from '../utils/nodemailer'
import { CREATOR } from '../utils'
@Injectable()
export class RegisterService {
registerMapper = new RegisterMapper()
constructor(
@Inject(CREATOR) private readonly repository: BaseRepository<Creator>,
) { }
async createAccount (doc: RegisterDto) {
const emailExist = await this.existByEmail(doc.email)
if (emailExist) {
return errors.EMAIL_EXIST()
}
const created = await this.repository.create(this.mapper.toDomain(doc))
await mailer(doc.email)
return created
}
private async existByEmail(email: string): Promise<boolean> {
console.log(email)
console.log(this.repository)
const response = await this.repository.get({ email })
return !!response.email;
}
}
inject-tokens.ts
export const CREATOR = 'CREATOR'
我正在尝试将存储库模式与 TypeScript 结合使用
现在我有 base.repository
实现了我需要的所有功能,我将其设为通用类型,我想在将模型注入 constructor
时传递模型,但出于某种原因,在传递值时,我有特定模型的未定义状态,我做错了什么?
在 console.log()
中显示模型未定义,而在文件 register.service.ts
中显示模型也未定义,但我将其作为通用传递。
register.service.ts
import { BaseRepository } from "../repositories/base.repository";
import { Creator } from '../data/models/Creator'
import { RegisterDto } from "../types/dtos/register.dto";
import { Injectable } from '@nestjs/common'
import { RegisterMapper } from '../mappers/register.mapper'
import { errors } from '../errors'
import { mailer } from '../utils/nodemailer'
@Injectable()
export class RegisterService {
constructor(
private readonly repository: BaseRepository<Creator>,
private readonly mapper: RegisterMapper
) { }
async createAccount (doc: RegisterDto) {
const emailExist = await this.existByEmail(doc.email)
if (emailExist) {
return errors.EMAIL_EXIST()
}
const created = await this.repository.create(this.mapper.toDomain(doc))
await mailer(doc.email)
return created
}
private async existByEmail(email: string): Promise<boolean> {
console.log(email)
console.log(this.repository)
const response = await this.repository.get({ email })
return !!response.email;
}
}
base.repository.ts
import { ModelType } from '@typegoose/typegoose/lib/types'
import { DuplicateKeyError } from '../errors/DuplicateKeyError'
import { DocumentNotFoundError } from '../errors/DocumentNotFoundError'
import { Model } from 'mongoose'
import { Inject, Injectable, Optional } from '@nestjs/common'
@Injectable()
export class BaseRepository<T = any> {
constructor(
@Optional() @Inject('MODEL') private Model: any
) { }
async create (object): Promise<T> {
const Model = this.Model
console.log(Model)
const uniqueKey = Model.getUniqueKey ? Model.getUniqueKey() : null
if (uniqueKey && object[uniqueKey]) {
const criteria = {
[uniqueKey]: object[uniqueKey]
}
const existing = await Model.findOne(criteria)
if (existing) {
throw new DuplicateKeyError(Model, criteria)
}
}
const model = new Model(object)
return model.save()
}
async update (criteria, object, options = {}) {
const Model = this.Model
const uniqueKey = Model.getUniqueKey ? Model.getUniqueKey() : '_id'
const data = { ...object }
delete data[uniqueKey]
delete data.createdAt
return this.updateRaw(criteria, { $set: { ...data } }, options)
}
async updateRaw (criteria, data, options = {}) {
const query = this._getDbQuery(criteria, options)
const result = await this.Model.findOneAndUpdate(query, data, { new: true, ...options })
if (!result) {
throw new DocumentNotFoundError(this.Model, query)
}
return result
}
async save (modelInstance) {
return modelInstance.save()
}
async get (criteria, options: any = {}): Promise<T | undefined> {
console.log(Model)
const promise = await this.Model.findOne(this._getDbQuery(criteria, options)).exec()
if (options.select) {
promise.select(options.select)
}
return promise
}
async find (criteria, options): Promise<ReturnType<ModelType<T>['find']>> {
return this.Model.find(this._getDbQuery(criteria, options))
}
async resolve (criteria): Promise<T> {
return this.Model.resolve(this._getDbQuery(criteria))
}
async count (query) {
return this.Model.countDocuments(this._getDbQuery(query))
}
async delete (criteria) {
return this.Model.remove(this._getDbQuery(criteria))
}
_getDbQuery (criteria, options: any = {}) {
if ('getDbQuery' in criteria) {
const dbQuery = criteria.getDbQuery(options)
return 'find' in dbQuery
? dbQuery.find
: dbQuery
} else {
return criteria
}
}
}
我应该怎么做才能获得此存储库中的实际模型?
我在存储库注入之前在每个服务中添加了注入令牌
现在代码如下所示
import { BaseRepository } from "../repositories/base.repository";
import { Creator } from '../data/models/Creator'
import { RegisterDto } from "../types/dtos/register.dto";
import { Injectable } from '@nestjs/common'
import { RegisterMapper } from '../mappers/register.mapper'
import { errors } from '../errors'
import { mailer } from '../utils/nodemailer'
import { CREATOR } from '../utils'
@Injectable()
export class RegisterService {
registerMapper = new RegisterMapper()
constructor(
@Inject(CREATOR) private readonly repository: BaseRepository<Creator>,
) { }
async createAccount (doc: RegisterDto) {
const emailExist = await this.existByEmail(doc.email)
if (emailExist) {
return errors.EMAIL_EXIST()
}
const created = await this.repository.create(this.mapper.toDomain(doc))
await mailer(doc.email)
return created
}
private async existByEmail(email: string): Promise<boolean> {
console.log(email)
console.log(this.repository)
const response = await this.repository.get({ email })
return !!response.email;
}
}
inject-tokens.ts
export const CREATOR = 'CREATOR'