title: I'd like to inject Repositories container at Service constructor using typedi
body: <p>I'd like to inject Repositories at my UserService.</p>
  <p>But i'm not sure how to do that.
  I'm using typescript, typedi and sequelize.</p>
  <p>I think, the Service is loaded more fast than loaders.</p>
  <p>When I try to inject my Repositories which I set at database loader, the error occur.</p>
  <p>The error like this : <strong>ServiceNotFoundError: Service with &quot;repositories&quot; identifier was not found in the container. Register it before usage via explicitly calling the &quot;Container.set&quot; function or using the &quot;@Service()&quot; decorator.</strong></p>
  <p>So, I checked &quot;userRepo&quot; with console.log and the result was undefined.
  I also checked Container.get('repositories') at CreateUser meathod, it loaded collectly. I mean, I can get my Container instance.</p>
  <p>I just can't load repositories instance at constructor.</p>
  <p>What should I do to load repositories at constructor?
  Should I change sequelize to typeorm to load this?</p>
  <pre><code>// ** UserService.ts **
  import { Inject, Service } from 'typedi';
  import { UserRepository } from '../repositories/user.repository';
  import { UserCreationAttributes } from '../models/interface/User.interface';
  import { User, UserModel, UserStatic } from '../models/User';
  
  @Service()
  export default class UserService {
    constructor(@Inject('repositories') private userRepo: UserRepository) {}
  
    public async CreateUser(userData: UserCreationAttributes): Promise&lt;boolean&gt; {
      try {
        await this.userRepo.create(userData);
        return true;
      } catch (err) {
        console.log(err);
        return false;
      }
    }
  }
  </code></pre>
  <pre><code>// ** Database Loader **
  import { Sequelize } from 'sequelize';
  import config from '../config';
  import Logger from './logger';
  import { UserStatic } from '../models/User';
  import { FeedStatic } from '../models/Feed';
  import { CommentStatic } from '../models/Comment';
  import { VerificationStatic } from '../models/Verification';
  import { initializeModels } from '../models';
  import { initializeRepositories, Repositories } from '../repositories';
  import { Container } from 'typedi';
  
  export interface Models {
    User: UserStatic;
    Feed: FeedStatic;
    Comment: CommentStatic;
    Verification: VerificationStatic;
  }
  
  export default async function loadSequelize() {
    const sequelize = new Sequelize(
      config.database,
      config.databaseUsername,
      config.databasePassword,
      {
        host: config.databaseHost,
        port: config.databasePort,
        dialect: 'postgres',
      },
    );
  
    try {
      await sequelize.authenticate();
      const models: Models = initializeModels(sequelize);
      const repositories: Repositories = initializeRepositories(models);
      await sequelize.sync({ force: true });
  
      // This part might be loaded after services were loaded
      Container.set('models', models);
      Container.set('repositories', repositories);
  
  
      console.log('load finish');
    } catch (err) {
      Logger.error(err);
    }
  }
  
  </code></pre>
  <pre><code>// ** ./repositories/index.ts **
  import { Models } from '../loaders/database';
  import { UserRepository } from './user.repository';
  
  export interface Repositories {
    UserRepository: UserRepository;
  }
  export const initializeRepositories = (models: Models): Repositories =&gt; {
    const usersRepository = new UserRepository(models.User);
    const repositories: Repositories = {
      UserRepository: usersRepository,
    };
    return repositories;
  };
  </code></pre>
  <pre><code>// ** ./repositories/base.repository.ts **
  import { Model, BuildOptions, FindOptions } from 'sequelize/types';
  import { IFilter } from './filter/base.filter';
  
  export type RichModel = typeof Model &amp; {
    new (values?: Record&lt;string, unknown&gt;, options?: BuildOptions): Model;
  };
  
  export interface IMeta {
    globalCount: number;
    countAfterFiltering: number;
  }
  
  export interface IWithMeta&lt;M extends Model&gt; {
    meta: IMeta;
    data: M[];
  }
  
  export abstract class BaseRepository&lt;
    M extends Model,
    C extends object,
    F extends IFilter = IFilter
  &gt; {
    constructor(public _model: RichModel, private filterFactory: new () =&gt; F) {}
  
    private async getCount(where?: Record&lt;string, unknown&gt;): Promise&lt;number&gt; {
      const count = await this._model.count({ where });
      return count;
    }
  
    async getAll(params?: FindOptions, filter?: F): Promise&lt;IWithMeta&lt;M&gt;&gt; {
      const { from: offset, count: limit } = filter || {};
      const result = await this._model.findAndCountAll({
        order: [['id', 'ASC']],
        offset: offset,
        limit: limit,
        ...params,
      });
  
      const globalCount = await this.getCount();
      const countAfterFiltering = ((result.count as unknown) as Record&lt;
        string,
        unknown
      &gt;[]).length;
  
      return {
        meta: { globalCount, countAfterFiltering },
        data: result.rows as M[],
      };
    }
  
    async getById(id: string | number): Promise&lt;M&gt; {
      const result = await this._model.findByPk(id);
      return result as M;
    }
  
    async get(where: Record&lt;string, unknown&gt;): Promise&lt;M&gt; {
      const result = await this._model.findOne({ where });
      return result as M;
    }
  
    async updateById(id: string | number, data: C): Promise&lt;M&gt; {
      const result = await this._model.update(data, {
        where: { id },
        returning: true,
      });
  
      const [, models] = result;
  
      return models[0] as M;
    }
  
    async deleteById(id: string | number): Promise&lt;void&gt; {
      await this._model.destroy({
        where: { id },
      });
    }
  
    async create(data: C): Promise&lt;M&gt; {
      const model = await this._model.create(data);
      return (model as unknown) as M;
    }
  }
  </code></pre>
  <pre><code>// ** ./repositories/user.repository.ts
  import { BaseRepository, IWithMeta, RichModel } from './base.repository';
  import { UserModel, UserStatic } from '../models/User';
  import { UserCreationAttributes } from '../models/interface/User.interface';
  import { IFilter } from './filter/base.filter';
  import { UserFilter } from './filter/user.filter';
  import { Service } from 'typedi';
  
  @Service()
  export class UserRepository extends BaseRepository&lt;
    UserModel,
    UserCreationAttributes,
    IFilter
  &gt; {
    constructor(private model: UserStatic) {
      super(&lt;RichModel&gt;model, IFilter);
    }
  
    async getAllUsers(): Promise&lt;IWithMeta&lt;UserModel&gt;&gt; {
      const users = await this.getAll();
      return users;
    }
  
    async getOneByFilter({
      email,
      password,
    }: UserFilter): Promise&lt;UserModel | null&gt; {
      const user = await this.model.findOne({
        where: {
          email,
          password,
        },
      });
      return user;
    }
  
    async getAdminOneByFilter({
      email,
      password,
    }: UserFilter): Promise&lt;UserModel | null&gt; {
      const user = await this.model.findOne({
        where: {
          email,
          password,
          isAdmin: true,
        },
      });
      return user;
    }
  }
  </code></pre>