Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tsyringe - Injecting a dependency with overloaded constuctor

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);
  }
[...]
like image 209
MattV Avatar asked Oct 17 '25 14:10

MattV


1 Answers

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"
],
like image 131
Wylliam Borba Bassos Avatar answered Oct 20 '25 05:10

Wylliam Borba Bassos