- Angular-like API.
- Lightweight.
- No dependencies.
- Hierarchical containers.
- Pluggable metadata annotator.
- Persistence control: singleton or per request (handy for backend) upcoming...
npm install --save container-ioc
import { Container, Inject } from 'container-ioc';
let container = new Container();
@Injectable()
class A {}
@Injectable()
class B {}
@Injectable()
class C {
constructor(@Inject('IB') public b: B) {
}
}
let providers = [
A,
{ token: 'IB', useClass: B },
{ token: C, useClass: C },
{ token: 'UseValue', useValue: 'any-primitive-or-object'},
{
token: 'FromFactory',
useFactory: () => {
return 'something';
}
},
{
token: 'FromFactoryWithInjections',
useFactory: (value, b, c) => {
return `${value + b.constructor.name + c.constructor.name}`;
},
inject: ['UseValue', 'IB', C]
}
];
container.register(providers);
let a: A = container.resolve(A);
let b: B = container.resolve('IB');
let c: C = container.resolve(C);
let value: string = container.resolve('UseValue');
let fromFactory: string = container.resolve('FromFactory');
let fromFactoryWithInjections: string = container.resolve('FromFactoryWithInjections');
Using string literals for tokens can become a head ache, use Injection Token instread. T in front of TFactory stands for token, but you can stick to your own name convention:
import { InjectionToken, Container } from 'container-ioc';
let container = new Container();
interface IFactory {
create(): any;
}
const TFactory = new InjectionToken<IFactory>('IFactory'); // T in TFactory stands for token
@Injectable()
class ConcreteFactory implements IFactory {}
container.register({ token: TFactory, useClass: ConcreteFactory });
let factory: IFactory = container.resolve(TFactory);
if a provider wasn't found in a container it will look up in ascendant containers if there's any:
import { Container } from 'container-ioc';
@Injectable()
class A {}
let parentContainer = new Container();
let childContainer = parentContainer.createScope();
parentContainer.register({ token: 'IA', useClass: A });
childContainer.resolve('IA');
By default metadata is assigned to static properties. If you want to use Reflect API for annotation, you can implement IMetadataAnnotator interface with your implementation using Reflect API. Then plug it into AnnotatorProvider
import { AnnotatorProvider, IMetadataAnnotator, Container } from 'container-ioc';
class ReflectMetadataAnnotator implements IMetadataAnnotator {
// your implementation
}
AnnotatorProvider.set(new ReflectMetadataAnnotator());
let container = new Container();
...
Feel free to submit a bug or a feature request. Or pick an issue from here and leave a comment with your proposal.
see CONTRIBUTION.md