使用 inversify 注入自定义存储库

问题描述

我正在用 inversify 练习 mikroorm。

我有TodoEntity

import { Entity,Property,PrimaryKey,EntityRepositoryType } from '@mikro-orm/core'
import { TodoRepository } from '../../repositories'


@Entity({tableName: 'todo'})
export class TodoEntity {

  // [EntityRepositoryType]?: TodoRepository;

  @PrimaryKey()
  id?: number

  @property()
  title: string

  @property()
  description: string

  constructor(title: string,description: string) {
    this.title = title
    this.description = description
  }
} 

这是自定义存储库 TodoRepository

import { EntityRepository } from '@mikro-orm/MysqL'
import { Repository } from '@mikro-orm/core'
import { TodoEntity } from '../models/entities'
import { injectable } from "inversify"


@injectable()
@Repository(TodoEntity)
export class TodoRepository extends EntityRepository<TodoEntity> {} 

我通过

repository注入到service
import { injectable,inject } from "inversify"
import { TodoRepository } from "../repositories"
import TYPES from "../../di/types"
import autoBind from "auto-bind";

@injectable()
export class TodoService {

  private todoRepository: TodoRepository

  constructor (@inject(TYPES.TodoRepository) todoRepository: TodoRepository) {
    this.todoRepository = todoRepository
    autoBind(this)
  }

  public async getTodos() {
    return await this.todoRepository.findAll()
  }
}

这是我的控制器

import { injectable,inject } from "inversify"
import { TodoService } from "../services/todoService"
import { Request,Response,NextFunction} from "express";
import TYPES from "../../di/types";
import autoBind from "auto-bind";

@injectable()
export class TodoController {

  todoService: TodoService

  constructor(@inject(TYPES.TodoService) todoService: TodoService) {
    this.todoService = todoService
    autoBind(this)
  }

  public async getAllTodos(req: Request,res: Response,next: NextFunction) {
    res.send(await this.todoService.getTodos())
  }
}

这是类型

const TYPES = {
  TodoRepository: Symbol.for("TodoRepository"),TodoService: Symbol.for("TodoService"),TodoController: Symbol.for("TodoController")
};

export default TYPES

容器

import { TodoRepository } from "../todos/repositories"
import { TodoService } from "../todos/services/todoService"
import { TodoController } from "../todos/controllers/todoController"
import { Container } from "inversify"
import TYPES from "./types"



const container = new Container();

container.bind<TodoController>(TYPES.TodoController).to(TodoController);
container.bind<TodoService>(TYPES.TodoService).to(TodoService);
container.bind<TodoRepository>(TYPES.TodoRepository).to(TodoRepository);


export { container }

如何将自定义存储库注入服务,我遇到错误提示 Error: Missing required @injectable annotation in: sqlEntityRepository

但是当我没有包含 repository 时,只有 servicecontroller 并且我尝试测试转储。 DI 只是正常工作

我正在关注这个例子Inversify example with mikro orm

但是在他没有使用自定义存储库的示例中,知道我可以从哪里开始解决问题吗?

解决方法

您应该能够使用 inversify 提供的装饰实用程序添加装饰器。

import { decorate,injectable } from "inversify";
import SomeClass from "some-module";

decorate(injectable(),SomeClass);
return SomeClass;

在此处阅读文档:https://github.com/inversify/InversifyJS/blob/master/wiki/inheritance.md#what-can-i-do-when-my-base-class-is-provided-by-a-third-party-module

还有全局容器选项 skipBaseClassChecks 将跳过对所有基类的 @injectable 检查。