node package manager

typeioc

Dependency injection container for node typescript / javascript

TypeIOC

...X Windows

Dependency injection container for node typescript / javascript.

Install typeioc

npm install typeioc
var typeioc = require('typeioc');

Assuming TestBase class and Test class exist somewhere

var containerBuilder = typeioc.createBuilder();
containerBuilder.register(TestBase).as(function() {return  new Test(); });
var container = containerBuilder.build();
var actual = container.resolve(TestBase);

Copy typeioc.d.ts definition file from d.ts folder to your project and reference it within ts files.

/// <reference path="typeioc.d.ts" />
import typeioc = require("typeioc");
 
var containerBuilder = typeioc.createBuilder();
containerBuilder.register<TestBase>(TestBase)
    .as(() => new Test());
var container = containerBuilder.build();
var actual = container.resolve<TestBase>(TestBase);
containerBuilder.register<Test2Base>(Test2Base)
    .as(() => new Test2());
containerBuilder.register<Test1Base>(Test1Base)
    .as((c) => {
        var test2 = c.resolve(Test2Base);
        return new Test3(test2);
    });
containerBuilder.register(Test2Base).asType(Test2);
containerBuilder.register(Tes1tBase).asType(Test3, Test2Base);
containerBuilder.register<Test1Base>(Test1Base)       // register component Test1Base
.as(() => new Test5())                                // as instance of Test5
.initializeBy((c, item) => {                          // invoke initialization on resolved instances
     item.coolMethodHere();
     return item;
})                                                   
.dispose((item : testData.Test5)  => item.Dispose())  // invoke disposal when disposing container
.named('Some Name')                                   // resolve with specific name
.within(typeioc.Types.Scope.Hierarchy)                // specifies instance re-usability
.ownedBy(typeioc.Types.Owner.Container);              // specifies instance ownership
 
// `.as(() => new Test5())` could be substituted with `asType(Test5)`.
// In this case Test5 is instantiated during resolution
 
 
 
var container = containerBuilder.build();                 // create an instance of container
 
container
.resolveWith<TestData.Test1Base>(Test1Base)    // resolve an instance of Test1Base
.args(arg1, arg2)                              // with arguments
.attempt()                                     // try resolve (do not throw if not found)
.name('someName')                              // with name (for named registrations)
.dependencies([d1, d2])                        // with dependencies (to substitute things Test1Base depends on)
.cache()                                       // with cached resolution value => container.cache.Test1Base
.exec();                                       // resolve

Compile ts files with experimentalDecorators and emitDecoratorMetadata flags.

var decorator = typeioc.createDecorator();
 
export class TestBase {
    public foo() {}
}
 
export class TestBase1 {
    public foo() {}
}
 
export class TestBase2 {
    public foo() {}
}
 
@decorator.provide(TestBase).register()
export class Test extends TestBase {
 
    public foo() {
        return 'Test';
    }
}
 
@decorator.provide<TestBase2>(TestBase2).register()
export class Test2 extends TestBase2 {
 
    public foo() {
        return 'Test2';
    }
}
 
@decorator.provide(TestBase1).register()
export class Test1 extends TestBase1 {
 
    constructor(private value1 : TestBase,
                @decorator.by(TestBase2).resolve() private value2) {
        super();
    }
 
    public foo() {
        return ['Test1 :', this.value1.foo(), this.value2.foo()].join(' ');
    }
}
 
var container = decorator.build();
var actual = container.resolve<TestBase1>(TestBase1);

Class level registration

@decorator.provide(service)           // also accepts generic parameter: provide<T>(service)
.initializeBy((c, item) => {
    item.someCoolMethod();
    return item;
})
.dispose(item => item.dispose())
.named('Some name')
.within(typeioc.Types.Scope.None)
.ownedBy(typeioc.Types.Owner.Container)
.register()
class Test {
    public foo() {}
}

Constructor parameters resolution

 
class Test {
    
    constructor(
       @decorator.by(service)        // service is optional and is not needed if _val type is specified
       .args(1, 2, 3)
       .attempt()
       .name()
       .cache()
       .resolve() private _val) {}
 
    public foo() {}
}

Copy typeioc.addons.d.ts definition file from d.ts folder to your project and reference it within ts files.

/// <reference path="typeioc.d.ts" />
/// <reference path="typeioc.addons.d.ts" />
 
var typeioc = require('typeioc');
var addons = require('typeioc/addons');
 
var containerBuilder = typeioc.createBuilder();
 
containerBuilder.register(Math)
    .as(c => {
 
    var interceptor = addons.Interceptors.create();
 
   return interceptor.intercept(Math, [{
            method: 'pow',
            type: addons.Interceptors.CallInfoType.Method,
            wrapper: function (callInfo:Addons.Interceptors.ICallInfo) {
 
                console.log('Before execute : ' + callInfo.args[0] + ' ' + callInfo.args[1]);
                var result = callInfo.invoke(callInfo.args);
                console.log('After execute : ' + result);
                return callInfo.args[0] + callInfo.args[1];
            }
        }]);
    });
 
var container = containerBuilder.build();
var actual = container.resolve<Math>(Math);
actual.pow(2,3); // 5
actual.log(1);   // still 0
  • - Type compliance checking.
  • - Late instances creation through lambda expressions.
  • - Dependencies resolution.
  • - Named instances resolution.
  • - Custom instance initialization.
  • - Custom instance disposal.
  • - Instance scoping.
  • - Instance ownership.
  • - Module registration
  • - Fluent API.
  • - Configuration (JS).
  • - Runtime / Dynamic dependencies substitution.
  • - Cached resolution results.
  • - Interceptors.
  • - ES7 decorators style resolution.
  • - ES6 codebase + weak references + promises.
  • - Instance lifetime scoping APIs extension.
  • - Group registration.
  • - Decorative style interceptors.
  • - In-browser usage support.
  • - Usage with 3d part libraries.
  • - Full API documentation.