@ukab/container
v0.1.0
Published
Ukab Ecosystem ioc container library
Downloads
3
Maintainers
Readme
Inversion of control
Container is a IoC packge for NodeJS. This package supports both ESM and CommonJs modules.
Installtion
npm i @ukab/container
Features
- multiple scoped containers
- register provider under custom name or custom identity
- class,function,string,symbol as injectable
- eagar resolution
- factory providers
- multiple scopes
- cross refer providers
- resolve without caching or saving
- call object method from container
- property handlers
- multiple ways of registering different kind of providers
- decorators: @Injectable(), @Inject()
- customizable behavior
- context based container
Usage
Note: You should install and import reflect-metadata before using this package.
1. using default container
import 'reflect-metadata';
import { Container, Injectable } from '@ukab/container';
class Router {
test() {
console.log('router test called')
}
}
// register router
Container.register(Router);
@Injectable()
class Test {
constructor(public router: Router) { }
test() {
this.router.test()
}
}
// register and get resolved instance
const instance = Container.resolve<Test>(Test);
instance.test();
2. creating and using container
import 'reflect-metadata';
import { Container, Injectable } from '@ukab/container';
const myContainer = Container.of('myContainer');
class Router {
test() {
console.log('router test called')
}
}
// register router
myContainer.register(Router);
@Injectable()
class Test {
constructor(public router: Router) { }
test() {
this.router.test()
}
}
// register and get resolved instance
const instance = myContainer.resolve<Test>(Test);
instance.test();
3. using provider with custom identity
import 'reflect-metadata';
import { Inject, Injectable, Container } from '@ukab/container';
class Router {
test() {
console.log('router test called')
}
}
// register router with custom identity
Container.register(Router, 'IRouter');
interface IRouter {
test(): void
}
@Injectable()
class Test {
constructor(@Inject('IRouter') public router: IRouter) {
}
test() {
this.router.test();
}
}
// register and get resolved instance
const instance = Container.resolve<Test>(Test);
instance.test();
4. injecting custom dependency in method
import 'reflect-metadata';
import { Inject, Injectable, Container } from '@ukab/container';
class Router {
test() {
console.log('router test called')
}
}
// register router with custom identity
Container.register(Router, 'IRouter');
interface IRouter {
test(): void
}
class User {
test() {
console.log('user test called')
}
}
// register user service
Container.register(User);
@Injectable()
class Test {
@Inject()
user: User
constructor(@Inject('IRouter') public router: IRouter) {
}
test(@Inject('p1') p1: number) {
this.router.test();
this.user.test();
console.log(p1);
}
}
Container.value<number>('p1', 1);
// register and call method with param injection
Container.register<Test>(Test);
Container.call(Test, 'test');
5. using context container
import 'reflect-metadata';
import { Inject, Injectable, Container, IocContext, Scope } from '.';
const container = Container.of('test');
@Injectable({ scope: Scope.Contextual })
class Test {
constructor(@Inject('p1') public p1: number) {
}
test() {
console.log('p1 value', this.p1);
}
}
container.register<Test>(Test);
// this context will use the given container
const context1 = new IocContext('random context id', container);
context1.set<string, number>('p1', 2);
// this context will use the given container
const context2 = new IocContext('random context id', container);
context2.set<string, number>('p1', 3);
const testFromContext2 = context2.get<Test>(Test);
testFromContext2.test() // p1 value 3
const testFromContext1 = context1.get<Test>(Test);
testFromContext1.test() // p1 value 2
Scope Boundry
- by default all injectables are singleton, you can configure them to be transient or contextual
- singleton injectables cannot have contextual or transient injectables, you can configure to allow transient injectables in singleton injectables