Skip to content

typesoft/container-ioc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

alt text

container-ioc

is a Dependency Injection / Inversion of Control (IoC) container package for Javascript and Node.js applications powered by Typescript . It manages the dependencies between classes, so that applications stay easy to change and maintain as they grow.

npm version Build Status npm Gitter chat license

Features:

Examples:

Installation:

npm install --save container-ioc 

Basics:

Code examples below are written in Typescript. Check examples/javascript for examples written in Javascript.

Step 1. Define your interfaces and types.

Possible values for types: Symbol, string, Object.

interface IApplication { run(): void; } interface IService { serve(): void; } const TApplication = Symbol('IApplication'); const TService = Symbol('IService');

Step 2. Declare dependencies with decorators Injectable and Inject.

import { Injectable, Inject } from 'container-ioc'; @Injectable() export class Application implements IApplication { constructor(@Inject(TService) private service: IService) {} run(): void { this.service.serve(); } } @Injectable() export class Service implements IService { serve(): void { // serves } }

Step 3. Create a container and register types in there.

import { Container } from 'container-ioc'; let container = new Container(); container.register([ { token: TApplication, useClass: Application }, { token: TService, useClass: Service } ]);

Step 4. Resolve value from the container.

let app = container.resolve(TApplication); app.run();

Step 2 for Javascript.

Since Javascript does not support parameter decorators, use alternative API for declaring dependencies. In this case we don't use Inject decorator. See examples/javascript for more.

@Injectable([TService]) class Service { constructor(service) { this.service = service; } }

Life Time control

By default, containers resolve singletons when using useClass and useFactory. Default life time for all items in a container can be set by passing an option object to it's contructor with defailtLifeTime attribute. Possible values: LifeTime.PerRequest (resolves instances) and LifeTime.Persistent (resolves singletons);

import { LifeTime } from 'container-ioc'; const container = new Container({ defaultLifeTime: LifeTime.PerRequest });

You can also specify life time individually for each item in a container by specifying lifeTime attribute.

container.register([ { token: TService, useClass: Service, lifeTime: LifeTime.PerRequest } ]);
container.register([ { token: TService, useFactory: () => { return { serve(): void {} } }, lifeTime: LifeTime.Persistent } ]);

Hierarchical containers

If a container can't find a value within itself, it will look it up in ascendant containers. There a 3 ways to set a parent for a container.

1. Container.createChild() method.
const parentContainer = new Container(); const childContainer = parentContainer.createChild();
2. Container.setParent() method.
const parent = new Container(); const child = new Container(); child.setParent(parent);
3. Via Container's constructor with options.
const parent = new Container(); const child = new Container({ parent: parent });

Using Factories

/* Without injections */ container.register([ { token: 'TokenForFactory', useFactory: () => { return 'any-value'; } } ]); /* With injections */ container.register([ { token: 'EnvProvider', useClass: EnvProvider }, { token: 'TokenForFactory', useFactory: (envProvider) => { // do something return 'something'; }, inject: ['EnvProvider'] } ]);

Using Values

container.register([ { token: 'IConfig', useValue: {}} ]);

Shortcut for Classes

container.register([ App ]);

Is the same as:

container.register([ { token: App, useClass: App } ]);

Contribution

Become a contributor to this project. Feel free to submit an issue or a pull request.

see CONTRIBUTION.md for more information.

Please see also our Code of Conduct.