Lightweight inversion of control container
Prerequisites
Language : Typescript 3+
In tsconfig.json
{
"experimentalDecorators": true
}
Installation
npm i @sbailleul/types_ioc
Usage
Dependency handling
You can't use interface for dependency injection cause interfaces are not compiled in javascript. To solve this limitation use full abstract class and implement these in concrete classes :
export abstract class BaseApplicationRepository{
abstract getAll(query: Query): Promise<{ count: number; rows: IApplicationModel[] }>
abstract delete(id: number): Promise<number>;
abstract getOne(id: any): Promise<IApplicationModel | null>;
}
@Injectable
export class SequelizeApplicationRepository implements BaseApplicationRepository{
async delete(id: number): Promise<number> {
return SequelizeApplicationModel.destroy({where: {id}});
}
async getAll(query: Query): Promise<{ count: number, rows: IApplicationModel[] }> {
return SequelizeApplicationModel.findAndCountAll({offset: query.offset, limit: query.limit});
}
async getOne(id: any): Promise<IApplicationModel | null> {
return SequelizeApplicationModel.findByPk(id);
}
}
Decorators
Injectable
@Injectable decorator indicate than your class is injectable in other classes, this decorator is mandatory
InjectionTarget
@InjectionTarget decorator indicate than your class will be target for injection, this decorator is mandatory
InjectedProperty
@InjectedProperty decorator indicate than your class property will be injected by ioc, specify base class name in parameter of decorator, for example:
@InjectionTarget
export class ApplicationService extends BaseService{
@InjectedProperty(BaseApplicationRepository)
protected readonly _repository: BaseApplicationRepository;
}
Add injection tags to ioc
WARNING : If you bind provider which has not @Injectable decorator the CoreContainer will throw critical exception.
Tags are usefull to specify which provider select in case of injection conflict :
CoreContainer.addInjectionTags('sequelize');
CoreContainer.bind(BaseApplicationRepository, {class: MongooseApplicationRepository, tags: 'mongoose' });
CoreContainer.bind(BaseApplicationRepository, {class: SequelizeApplicationRepository, tags: 'sequelize');
In this case for BaseApplicationRepository provider container will select SequelizeApplicationRepository class.
Resolve registered dependencies
CoreContainer.resolve();