javascript - tsyringe - Injecting a dependency with overloaded constuctor - Stack Overflow

Hi friends how are you doing?I'm trying to do something different, I don't know if it's

Hi friends how are you doing?

I'm trying to do something different, I don't know if it's away from the concept itself but it would help me to achieve what I'm trying to do in an elegant way.

I'm using a repository pattern and in the implementation I want to use a overloaded constructor and use an optional argument, basically passing some adicional information when it's needed.

The problem is, it's working great when the constructor is empty, but by the time change de signature to receive one more argument, the TSYSRINGE throws an execption.

I Really think that I'm missing something really simple, but I can't figure what. Could you please help me on this one? Thanks

ERROR:

Error: Cannot inject the dependency at position #0 of "ListProjectsServices" constructor. Reason:
    TypeInfo not known for "ProjectsRepository"

Controller

export default class ProjectsController {
  public async index(request: Request, response: Response): Promise<void> {
    const listProjectsServices = container.resolve(ListProjectsServices);
    const projects = await listProjectsServices.execute();
    response.json(projects);
  }

Service

@injectable()
export default class ListProjectsServices {

  constructor(
    @inject('ProjectsRepository')
    private ProjectsRepository: IProjectsRepository,
  ) {}

  public async execute(): Promise<Projects[]> {
    const ProjectsList = await this.ProjectsRepository.findAllProjects();
    return ProjectsList;
  }
}

Container - to create the injection token


container.registerSingleton<IProjectsRepository>(
  'ProjectsRepository',
  ProjectsRepository,
);

Repository - Notice the extra_details argument in the constructor

after adding it, the problem occurs


@EntityRepository(Projects)
export default class ProjectsRepository implements IProjectsRepository {
  private ormRepository: Repository<Projects>;

  constructor(extra_details?: object) {
    this.ormRepository = getRepository(Projects);
  }
[...]

Hi friends how are you doing?

I'm trying to do something different, I don't know if it's away from the concept itself but it would help me to achieve what I'm trying to do in an elegant way.

I'm using a repository pattern and in the implementation I want to use a overloaded constructor and use an optional argument, basically passing some adicional information when it's needed.

The problem is, it's working great when the constructor is empty, but by the time change de signature to receive one more argument, the TSYSRINGE throws an execption.

I Really think that I'm missing something really simple, but I can't figure what. Could you please help me on this one? Thanks

ERROR:

Error: Cannot inject the dependency at position #0 of "ListProjectsServices" constructor. Reason:
    TypeInfo not known for "ProjectsRepository"

Controller

export default class ProjectsController {
  public async index(request: Request, response: Response): Promise<void> {
    const listProjectsServices = container.resolve(ListProjectsServices);
    const projects = await listProjectsServices.execute();
    response.json(projects);
  }

Service

@injectable()
export default class ListProjectsServices {

  constructor(
    @inject('ProjectsRepository')
    private ProjectsRepository: IProjectsRepository,
  ) {}

  public async execute(): Promise<Projects[]> {
    const ProjectsList = await this.ProjectsRepository.findAllProjects();
    return ProjectsList;
  }
}

Container - to create the injection token


container.registerSingleton<IProjectsRepository>(
  'ProjectsRepository',
  ProjectsRepository,
);

Repository - Notice the extra_details argument in the constructor

after adding it, the problem occurs


@EntityRepository(Projects)
export default class ProjectsRepository implements IProjectsRepository {
  private ormRepository: Repository<Projects>;

  constructor(extra_details?: object) {
    this.ormRepository = getRepository(Projects);
  }
[...]
Share Improve this question edited Sep 23, 2020 at 16:24 MattV asked Sep 23, 2020 at 16:15 MattVMattV 3544 silver badges15 bronze badges 2
  • Hey buddy, did you solved it? – Rhadamez Gindri Hercilio Commented Oct 17, 2020 at 22:34
  • 1 No really friend, in fact I had to change the strategy. – MattV Commented Oct 19, 2020 at 23:29
Add a ment  | 

2 Answers 2

Reset to default 4

Today I went through this same problem. Read this article on circular dependencies. It tells us to use the delay function imported from tsyringe. In the article, he tells us to use the delay inside the constructor. But you, like me, are not directly sending the object in the inject, but a registered key. Then you must use the delay in your container file, around the repository object try this:

import { container, delay } from 'tsyringe';

container.registerSingleton<IProjectsRepository>(
  'ProjectsRepository',
  delay(() => ProjectsRepository),
);

Insert the delay in all your injections that depend on an asynchronous repository

It can also be an error in the seo ormconfig.json, in the entities property. Make sure the path is pointing to your entities:

"entities": [
  "./src/modules/**/infra/typeorm/entities/*.ts"
],

We had the same problem here and we didn't want to have to use the delay function in the controller because we would be breaking the dependency injection principle... One way to solve the problem is to import your "Container" file into the main project file, in our case called "server.ts" and installing a lib called "reflect-metadata".

server.ts:

import * as dotenv from 'dotenv';

dotenv.config();

import express from 'express';
import 'express-async-errors';
import 'reflect-metadata'; // here is reflect-metadata import!
import config from './config/application';
import './infra/container'; // here is container import!
import { errorHandler } from './infra/http/middlewares/errorHandler';
import useSwagger from './infra/http/middlewares/swagger';
import { routes } from './infra/http/routes';
import { morganMiddleware } from './infra/logging/morgan';

export const app = express();

app.use(morganMiddleware);
app.use(express.json());
app.use(`${config.prefix}/api`, routes);
app.use(`${config.prefix}`, express.static('public'));
useSwagger(`${config.prefix}/api/docs`, app);
app.all(`${config.prefix}`, (_, res) => res.redirect(`${config.prefix}/api/docs`));
app.use(errorHandler);

container/index.ts:

import { container } from 'tsyringe';
import { RecurrenceNotificationUseCase } from '../../application/useCases/RecurrenceNotificationUseCase';
import { PubSubImplementation } from '../pubsub/PubSubImplementation';

container.registerSingleton('IPubSub', PubSubImplementation);
container.registerSingleton('IRecurrenceNotificationUseCase', RecurrenceNotificationUseCase);

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744292229a4567088.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信