npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@appolo/inject

v8.0.20

Published

dependency injection for node js

Downloads

798

Readme

Appolo Inject

Build Status Dependencies status NPM version npm Downloads Known Vulnerabilities

es6 Dependency Injection framework for nodejs build with typescript.
appolo-inject is part for the appolo framework.

Installation

npm install appolo-inject --save  

Typescript

appolo-inject requires TypeScript compiler version > 2.1 and the following settings in tsconfig.json:

{
    "experimentalDecorators": true
}

Usage

Creating injection container

var inject = require('@appolo/inject');  
var injector = inject.createContainer();  

injector.addDefinitions({...});  
injector.initialize();  

Add Definitions

the definition object key is used for object class id.

var inject = require('@appolo/inject');  
class FooController{ }  

var injector = inject.createContainer();  
injector.addDefinitions({  fooController: { type: FooController }});  
injector.initialize();   

or with injector define

let injector = inject.createContainer();  
injector.register('fooController',FooController);  
injector.initialize();  
  
//get fooController instance from the injector  
let fooController = injector.get('fooController');  

or with decorators

@define()
class FooController{ }   

//or with custom id
@define("someId")
class FooController2{ }

let injector = inject.createContainer();  
injector.register(FooController);  
injector.initialize();  
  
//get fooController instance from the injector  
let fooController = injector.get('fooController');//or
let fooController2 = injector.get(FooController); 
let someController = injector.get('someId');  

Get Object

get object from the injector by id or class name if the object is not singleton you will get new instance every time.

@define()
class FooController{ }  
  
let injector = inject.createContainer();  
 injector.register(FooController);
 injector.initialize();  

let fooController = injector.get<FooController>('fooController');  
let fooController2 = injector.get<FooController>('fooController');  
  
console.log(fooController === fooController2) // false  
  

Singleton

the class will be created only once and injector will return the same instance every time.

@define()
@singleton()
class FooController{}  
  
let injector = inject.createContainer();  
injector.register(FooController);
injector.initialize();  

let fooController = injector.get<FooController>(FooController);  
let fooController2 = injector.get<FooController>('fooController');  
  
console.log(fooController === fooController2) // true  
  

Inject Constructor Arguments

you can inject objects to constructor arguments you can inject object instance by id or by value.
it is not recommended to inject objects to constructor because you can easily get circular reference.

@define()
@singleton()
class FooManager{  
    get name () { 
        return 'foo'
    }
} 
@define()
class BuzzController{  
	constructor (@injectParam() fooManager:FooManager,name:string) { 
	    this.fooManager = fooManager; 
	    this.name = name; 
	} 
	name () {
	    return   this.fooManager.name +this.name
	}
}  
  
var injector = inject.createContainer();  
injector.registerMulti([FooManager,BuzzController]); 
injector.initialize();  

var buzzController = injector.getObject<BuzzController>(BuzzController,["buzz"]);  
console.log(buzzController.name()) // foobuzz 

Inject with runtime arguments

@define()
class BuzzController{  
	constructor(name:string) { 
	    this.name = name; 
	} 
	get name () {
	    return this.name
	}
}  

let injector = inject.createContainer();  
injector.register(BuzzController);
injector.initialize();

let buzzController = injector.get<BuzzController>('buzzController',['buzz']);  
console.log(buzzController.name) // buzz 

Init Method

The init method will be called after all instances were created and all the properties injected.

@define()
@singleton()
class FooManager{  
    get name(){return 'foo'; }
}  
@define()  
class FooController{  
    @inject() fooManager:FooManager
    @initMethod()
    initialize(){ this.name = this.fooManager.name } 
    get name () {return this.name}
}  
  
let injector = inject.createContainer();
injector.registerMulti([FooController,FooManager]); 
injector.initialize();

var fooController = injector.getObject('fooController');  
fooController.name // foo   

Inject Instance

inject will try to inject object id to the same property name.

@define()
@singleton()
class FooManager{  
    get name () { return 'foo' }
}  
@define()
@singleton()  
class BarManager{  
    get name () { return 'bar' }
}  

@define() 
class BuzzController{ 
    @inject() fooManager:FooManager; 
    @inject() barManager:BarManager; 
	
    get name () { return this.fooManager.name + this.barManager.name }
}  
  
var injector = inject.createContainer(); 
injector.registerMulti([BuzzController,FooManager,BarManager]);  injector.initialize();  

var buzzController = injector.get<BuzzController>(BuzzController);  
console.log(buzzController.name) // foobar   

Inject Instance By Name

you can set the name of the property the object will be injected to.

@define()
@singleton()
class FooManager{  
    get name() {return 'foo'}
}  
@define()
@singleton()  
class BarManager{  
    get name() { return 'bar'}
}  
@deine()  
class BuzzController{
    @inject(FooManager) foo:FooManager; 
    @inject('barManager') bar:BarManager;  
	
    get name () { return this.foo.name + this.bar.name}
 }  
  
var injector = inject.createContainer(); 
injector.registerMulti([BuzzController,FooManager,BarManager]);  injector.initialize();
  
var buzzController = injector.get('buzzController');  
console.log(buzzController.name) // foobar ```  

Inject Property Value

you can inject any value to object property.

@define()  
class FooManager{
    @injectValue('foo') name:string
    get name () {return this.name;}
 }  
 
@define() 
class BuzzController{
    @inject(FooManager) foo:FooManager;
  
    get name () { return this.foo.name}
}  
  
let injector = inject.createContainer(); 
injector.registerMulti([BuzzController,FooManager]);  injector.initialize();  

let buzzController = injector.get('buzzController');  
console.log(buzzController.name()) // foo   

Inject Method Param

you can inject instance to method param.

@define()  
class FooManager{
    get name () {return "foo"}
}  
 
@define() 
class BuzzController{ 
    public name (@injectParam(FooManager) foo:FooManager) { 
        return this.foo.name
    }
}

let injector = inject.createContainer(); 
injector.registerMulti([BuzzController,FooManager]);  
injector.initialize();  

let buzzController = injector.get('buzzController');  
console.log(buzzController.name()) // foo   
  

Inject Factory

factory object must have implement get method that will be called in order to inject the object instance.
the get method can return promise;

@define()
@singleton()
class BarManager{  
    get name(){return 'bar'; }
}  

@define()
@singleton()
@factory()  
class Foo implements IFactory<BarManager>{
    @inject() barManager:BarManager;  
    async get ():Promise<BarManager> {
        return this.barManager;
    }
}
  
@define()  
class BuzzController{
    @inject() foo:BarManager  
    get name () {return this.foo.name}
 }  
  
let injector = inject.createContainer(); 
injector.registerMulti([BuzzController,FooManager]); 
injector.initialize();

var buzzController = injector.getObject('buzzController');  
console.log(buzzController.name) // bar  

Inject Factory Method

factory method is a function that will return the injected object.
this is useful the create many instances of the same class.

@define()
class  Person{  
    constructor (name) { 
        this.name = name; 
    } 
    get name(){return this.name; }
}  
@define() 
class FooController{ 
    @injectFactoryMethod(Person) createPerson:(name)=>Person  
    name () { return this.createPerson('foo').name; }
}  
  
let injector = inject.createContainer();
injector.registerMulti([FooController,Person]); 
injector.initialize();
  
var buzzController = injector.getObject('fooController');  
console.log(fooController.name) // foo 

Alias

you can add alias names to classes and get all the classes by single alias. all the alias must be singletons

interface IHandler{
    name:string
}

@define()
@singleton()
@alias('IHandler')
class FooManager implements IHandler {  
    get name(){return 'foo'}
}  
@define()
@singleton()
@alias('IHandler') 
class BarManager implements IHandler{  
    get name(){return 'bar'}
}  

@define()  
class BuzzController{
    @injectAlias('handler') allHandlers:IHandler[]  
 
    get name(){      
        return this.allHandlers.map(obj =>obj.name).join(); 
    }
}  
  
let injector = inject.createContainer();
injector.registerMulti([BuzzController,BarManager,FooManager]); 
injector.initialize();

var buzzController = injector.getObject('buzzController');  
buzzController.name // foobar 

Alias Factory

you can add alias factory names to classes and get all the classes new instance by factory method.

interface IHandler{
    name:string
}

@define()
@aliasFactory('IHandler')
class FooManager implements IHandler{  
    constructor (private _name:string) {  } 
    get name():string{ return this._name }
}  
@define()
@aliasFactory('IHandler')  
class BarManager implements IHandler{  
    public name:string
    constructor (private _name:string) {  } 
    get name():string{ return this._name }
}  

@define() 
class BuzzController{  
    @injectAliasFactory('IHandler') allHandlers:((name:string)=>IHandler)[] 
	
    get name(){      
        return this.allHandlers.map((createHandler,index) =>createHandler(index).name).join(); 
    }  
  
let injector = inject.createContainer();
injector.registerMulti([BuzzController,BarManager,FooManager]); 
injector.initialize();

var buzzController = injector.getObject('buzzController');  
buzzController.name // 01 

Inject Property Array

you can inject array of properties by reference or by value.

@define()
@singleton() 
class FooManager{  
    get name () { return 'foo' }
 }  
  
@define()
@singleton() 
class BarManager{  
    get name () {return 'bar'}
}  
@define()  
class BuzzController{ 
    @injectArray([FooManager,BarManager]) objects:any[]
	
    name () { this.objects.map(obj=>obj.name).join() }
}  
  
let injector = inject.createContainer(); 
injector.registerMulti([BuzzController,FooManager,BarManager]);  injector.initialize(); 

var buzzController = injector.getObject('buzzController');  
buzzController.name // foobar   

Inject Property Dictionary

you can inject dictionary of properties by reference or by value.

@define()
@singleton() 
class FooManager{  
	get name () { return 'foo' }
 }  
  
@define()
@singleton() 
class BarManager{  
	get name () {return 'bar'}
}  
@define() 
class BuzzController{
    @injectDictionary({foo:FooManager,bar:BarManager}) objects:any[]	  
    get name () {return this.objects.foo.name + this.objects.bar.name + this.objects.baz;}
}  
  
let injector = inject.createContainer(); 
injector.registerMulti([BuzzController,FooManager,BarManager]);  injector.initialize();
 
var buzzController = injector.getObject('buzzController');  
buzzController.name // foobarbaz   

Inject Property From Object Property

you can inject property from other object property.

@define()
@singleton()
class FooManager{  
	public name =  'foo';
}  
@define()
class BuzzController{  
    @injectObjectProperty(FooManager,'name') otherObjectProperty	  
	
    name () {return return this.otherObjectProperty;}
}  
  
let injector = inject.createContainer(); 
injector.registerMulti([BuzzController,FooManager]);  injector.initialize();

let buzzController = injector.getObject('buzzController');  
buzzController.name() // foo  

Injector Aware

you can get reference to the injector container by adding injectorAware the injector will be injected to $injector property.

@define()
@injectorAware()
class FooController{
    @initMethod()
    initialize(){ this.$injector.getObject('foo') }
}  

Tests

grunt test

License

The appolo inject library is released under the MIT license. So feel free to modify and distribute it as you wish.