I have a sequelize-typescript that defines a mysql db object:
const DBInstance = new Sequelize(config.db.database, config.db.username, config.db.password, {
host: config.db.host,
dialect: config.db.dialect as Dialect,
repositoryMode: true,
});
export default DBInstance;
And then I try to inject this instance to the repository class:
@injectable()
export default class AppDataRepository implements IAppMetaDataRepository {
private readonly repository: Repository<AppData>;
constructor(db: Sequelize) {
this.repository = db.getRepository(AppMetaData);
}
findOne = async (): Promise<AppEntity | null> => {
const result = await this.repository.findOne<AppData>();
if (!result) {
return null;
}
const data = result.get();
return new AppDataEntity(data.id, data.name, data.version, data.createdAt, data.updatedAt);
};
}
With the binding in config:
import MySqlInstance from '@DBConnection/MysqlInstance';
container.bind<Sequelize>(types.INVERSIFY_SYMBOL.Sequelize).toConstantValue(MySqlInstance);
Where the MySqlInstance
is the instance exported DBInstance
. But the above code still generates the error:
No matching bindings found for serviceIdentifier: Sequelize {"stack":"Error: No matching bindings found for serviceIdentifier: Sequelize
I have to use a Sequelize instance with the config value that I provided in the DBInstance
initialization but not sure how can I do that with inversify
?
Directory structure:
.
├── db.ts
├── index.ts
├── ioc
│ ├── interfaces.ts
│ ├── ioc.ts
│ └── types.ts
├── models
│ ├── AppMetaData.ts
│ └── index.ts
└── repositories
└── AppDataRepository.ts
3 directories, 8 files
models/AppMetaData.ts
:
import { Model, Table } from 'sequelize-typescript';
@Table
export class AppMetaData extends Model {}
models/index.ts
:
export * from './AppMetaData';
ioc/interfaces.ts
:
import { Sequelize } from 'sequelize-typescript';
export type SequelizeInstance = InstanceType<typeof Sequelize>;
export interface IAppMetaDataRepository {
test(): void;
findOne(): Promise<any>;
}
ioc/types.ts
:
const TYPES = {
Sequelize: Symbol.for('Sequelize'),
AppDataRepository: Symbol.for('AppDataRepository'),
};
export { TYPES };
ioc/ioc.ts
:
import { Container } from 'inversify';
import MySqlInstance from '../db';
import { TYPES } from './types';
import AppDataRepository from '../repositories/AppDataRepository';
import { SequelizeInstance } from './interfaces';
const container = new Container();
container.bind<SequelizeInstance>(TYPES.Sequelize).toConstantValue(MySqlInstance);
container.bind<AppDataRepository>(TYPES.AppDataRepository).to(AppDataRepository);
export { container };
repositories/AppDataRepository.ts
:
import { inject, injectable } from 'inversify';
import { Repository } from 'sequelize-typescript';
import { IAppMetaDataRepository, SequelizeInstance } from '../ioc/interfaces';
import { TYPES } from '../ioc/types';
import { AppMetaData } from '../models/AppMetaData';
@injectable()
export default class AppDataRepository implements IAppMetaDataRepository {
private sequelize: SequelizeInstance;
private readonly repository: Repository<AppMetaData>;
constructor(@inject(TYPES.Sequelize) sequelize: SequelizeInstance) {
this.sequelize = sequelize;
this.repository = sequelize.getRepository(AppMetaData);
}
test() {
console.log(typeof this.sequelize.authenticate === 'function'); // true
console.log(this.repository.getTableName().toString());
}
async findOne() {
const result = await this.repository.findOne<AppMetaData>();
if (!result) {
return null;
}
// ...
}
}
db.ts
:
import { Sequelize } from 'sequelize-typescript';
import { Dialect } from 'sequelize/types';
import * as models from './models';
const config = {
db: {
database: 'test',
username: 'root',
password: '',
host: '127.0.0.1',
dialect: 'sqlite',
},
};
const DBInstance = new Sequelize(config.db.database, config.db.username, config.db.password, {
host: config.db.host,
dialect: config.db.dialect as Dialect,
storage: ':memory:',
repositoryMode: true,
models: Object.values(models),
});
export default DBInstance;
index.ts
:
import 'reflect-metadata';
import { container } from './ioc/ioc';
import { IAppMetaDataRepository } from './ioc/interfaces';
import { TYPES } from './ioc/types';
const appDataRepository = container.get<IAppMetaDataRepository>(TYPES.AppDataRepository);
appDataRepository.test();
Run command npx ts-node ./index.ts
, execution result:
true
AppMetaData
package versions:
"inversify": "^5.1.1",
"sequelize-typescript": "^1.0.0",
"sequelize": "^5.21.3",
"typescript": "^4.9.5",
"reflect-metadata": "^0.1.13"