title: I'd like to DI for repository interface and service interface like Spring using typedi
body: <p>I'd like to DI for repository interface and service interface like Spring using typedi.</p>
  <p>Below code (example code of DI for repository) is working correctly when calling api.</p>
  <p>Repository</p>
  <pre class="lang-js prettyprint-override"><code>import { Service } from &quot;typedi&quot;;
  import { EntityRepository, Repository } from &quot;typeorm&quot;;
  import { User } from &quot;../entity/User&quot;;
  
  export interface IUserRepository {
    findAllUsers();
  
    findUserByUserId(id: number);
  
    addUser(user: any);
  
    removeUserByUserId(user: any);
  }
  
  @Service()
  @EntityRepository(User)
  export class UserRepository
    extends Repository&lt;User&gt;
    implements IUserRepository {
    findAllUsers() {
      return this.find();
    }
  
    findUserByUserId(id: number) {
      return this.findOne({ id });
    }
  
    addUser(user: any) {
      return this.save(user);
    }
  
    removeUserByUserId(user: any) {
      return this.remove(user);
    }
  }
  </code></pre>
  <p>Service</p>
  <pre class="lang-js prettyprint-override"><code>import { Service } from &quot;typedi&quot;;
  import { InjectRepository } from &quot;typeorm-typedi-extensions&quot;;
  import { User } from &quot;../entity/User&quot;;
  import { UserRepository } from &quot;../repository/userRepository&quot;;
  
  export interface IUserService {
    all();
  
    one(id: any);
  
    save(user: any);
  
    remove(id: any);
  }
  
  @Service()
  export class UserService implements IUserService {
    @InjectRepository(User)
    private userRepository: UserRepository;
  
    async all() {
      return this.userRepository.findAllUsers();
    }
  
    async one(id: any) {
      let user = await this.userRepository.findUserByUserId(id);
      if (typeof user === &quot;undefined&quot;) {
        throw new Error(`userId ${id} is not found.`);
      }
      return user;
    }
  
    async save(user: any) {
      return this.userRepository.addUser(user);
    }
  
    async remove(id: any) {
      let userToRemove = await this.userRepository.findUserByUserId(id);
      if (typeof userToRemove === &quot;undefined&quot;) {
        throw new Error(`userId ${id} is not found.`);
      }
      return this.userRepository.removeUserByUserId(userToRemove);
    }
  }
  </code></pre>
  <p>However, when I'd like to inject repository using interface, it does not work correctly and occur the error message.<br />
  The build is succes. The error message is occur when calling api<br />
  In addition, error message are different for the first time and the second time later when call api.<br />
  like this</p>
  <p>Repository</p>
  <pre class="lang-js prettyprint-override"><code>
  import { Service } from &quot;typedi&quot;;
  import { InjectRepository } from &quot;typeorm-typedi-extensions&quot;;
  import { User } from &quot;../entity/User&quot;;
  import { UserRepository } from &quot;../repository/userRepository&quot;;
  
  ...
  
  @Service()
  export class UserService implements IUserService {
    @InjectRepository(User)
    private userRepository: UserRepository;
  
    async all() {
      return this.userRepository.findAllUsers();
    }
  
    ...
  }
  </code></pre>
  <p>Error message of first time.</p>
  <pre class="lang-json prettyprint-override"><code>{
    &quot;name&quot;: &quot;CustomRepositoryNotFoundError&quot;,
    &quot;message&quot;: &quot;Custom repository Object was not found. Did you forgot to put @EntityRepository decorator on it?&quot;,
    &quot;stack&quot;: &quot;CustomRepositoryNotFoundError: Custom repository Object was not found. Did you forgot to put @EntityRepository decorator on it? (The following is omitted)&quot;
  }
  </code></pre>
  <p>Error message of second time later.</p>
  <pre class="lang-json prettyprint-override"><code>{
    &quot;name&quot;: &quot;TypeError&quot;,
    &quot;message&quot;: &quot;Cannot read property 'all' of undefined&quot;,
    &quot;stack&quot;: &quot;TypeError: Cannot read property 'all' of undefined(The following is omitted)&quot;
  }
  </code></pre>
  <p>Service does not work well either.</p>
  <p>Below code is success code.</p>
  <p>Controller</p>
  <pre class="lang-js prettyprint-override"><code>import {
    Get,
    JsonController,
    OnUndefined,
    Param,
    Post,
    Body,
    Delete,
  } from &quot;routing-controllers&quot;;
  import { Inject, Service } from &quot;typedi&quot;;
  import { UserService } from &quot;../service/userService&quot;;
  
  @Service()
  @JsonController(&quot;/users&quot;)
  export class UserRestController {
    @Inject()
    private userService: UserService;
  
    @Get(&quot;/&quot;)
    getAll() {
      return this.userService.all();
    }
  
    @Get(&quot;/:id&quot;)
    @OnUndefined(404)
    getOne(@Param(&quot;id&quot;) id: number) {
      return this.userService.one(id);
    }
  
    @Post(&quot;/&quot;)
    add(@Body() user: any) {
      return this.userService.save(user);
    }
  
    @Delete(&quot;/:id&quot;)
    delete(@Param(&quot;id&quot;) id: number) {
      return this.userService.remove(id);
    }
  }
  </code></pre>
  <p>But the below is not work well.
  In this case, even the build does not work.</p>
  <p>Controller</p>
  <pre class="lang-js prettyprint-override"><code>import {
    Get,
    JsonController,
    OnUndefined,
    Param,
    Post,
    Body,
    Delete,
  } from &quot;routing-controllers&quot;;
  import { Inject, Service } from &quot;typedi&quot;;
  import { IUserService } from &quot;../service/userService&quot;;
  
  @Service()
  @JsonController(&quot;/users&quot;)
  export class UserRestController {
    @Inject()
    private userService: IUserService;
  
    @Get(&quot;/&quot;)
    getAll() {
      return this.userService.all();
    }
  
    @Get(&quot;/:id&quot;)
    @OnUndefined(404)
    getOne(@Param(&quot;id&quot;) id: number) {
      return this.userService.one(id);
    }
  
    @Post(&quot;/&quot;)
    add(@Body() user: any) {
      return this.userService.save(user);
    }
  
    @Delete(&quot;/:id&quot;)
    delete(@Param(&quot;id&quot;) id: number) {
      return this.userService.remove(id);
    }
  }
  
  </code></pre>
  <p>Error Message</p>
  <pre><code>CannotInjectValueError: Cannot inject value into &quot;UserRestController.userService&quot;. Please make sure you setup reflect-metadata properly and you don't use interfaces without service tokens as injection value.
  </code></pre>
  <p>As described at the beginning, I'd like to DI for repository interface and service interface like Spring using typedi.<br />
  TypeDI cannnot using like this?
  or my code is wrong?
  Please help me.<br />
  Thank you.</p>