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

@hashstack/node-injection

v1.1.1

Published

Decorator based dependency / service injection for NodeJS and TypeScript inspired from Angular and Spring.

Downloads

11

Readme

Node Injection

Build Status codecov npm (scoped)

Decorator based service / dependency injection for NodeJS and Typescript inspired from Angular and Spring.

Getting started

Node Injection allows you to develop services that can be share throughout your application. Each service has a single instance which can be injected into other services, controllers, classes etc.

Here is a basic example of how to use Node Injection:

// 1. Import ES6 polyfills

import "reflect-metadata";
import "es6-shim";

// 2. Create a service

@Service()
class MyService {

	private beeps: number = 0;

	beep(): string {
		this.beeps++;
		console.log(this.beeps);
	}
}

// 3. Inject your service
 
class A {
	@Inject()
	myService: MyService;
	
	constructor() {
		this.myService.beep();
	}
}

class B {
	@Inject()
	myService: MyService;
	
	constructor() {
		this.myService.beep();
	}
}

new A(); // prints "1" to the console
new B(); // prints "2" to the console

Services do not need to use @Inject(): you just declare in their constructor the services to inject, and Node Injection injects them automatically:

@Service()
class A {
	constructor(private myService: MyService) {
		this.myService.beep();
	}
}

Installing

  1. Install module:
    npm install node-injection --save
  2. If you are targeting ES5, install reflect-metadata and es6-shim:
    npm install reflect-metadata es6-shim --save
    and make sure to import it in the global scope (place it at the beginning of your application):
    import 'es6-shim';
    import 'reflect-metadata';
  3. In your tsconfig.json, make sure you have the following options:
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,

Documentation

Node Injection annotations are built with simplicity, clearness and conciseness in mind. The full list of features they allow is described below.

Services

Basic usage

This class decorator registers a class as a service.

@Service()
class A {
	
}

Node Injection creates a single instance of this class. When another class or service injects this service, they access the same instance.

Services can rely on other services, all you need to do is declare dependencies in their constructor and they will automatically be injected with the appropriate instance at runtime.

@Service()
class A {
	constructor(private myService: MyService) {
		// this.myService....
	}
}

You will get an error if you try to inject a service that is not registered (i.e. is not annotated with @Service()).

Also note that services are identified by their class name. Hence, you cannot register two classes with the same name as services.

Advanced configuration

The @Service() decorator can be given a configuration object to alter its behavior.

| Property | Type | Description | Example | | ------------- | ------- | ----------- | ------- | | name | String | Override the name used to register the service. See usage with uglified code. | @Service({name: 'MyService'}) | | injectable | Boolean | When set to false, the service will not be added to the registry and hence will not be injectable in other components. This option is useful when you only want constructor parameters to be injected automatically. | @Service({injectable: false}) |

Usage with uglified code

By default, Node Injection uses Function.prototype.name to determine the name of the service to register (unless one is specified), and also the type of service to inject. When using this library in uglyfied code (Webpack.optimize.UglifyJsPlugin, UglifyJS...), function names are generally mangled (replaced by shorter names). This will cause service registration conflicts and injection errors.

There are two ways to prevent this problem:

  1. Provide a name for each of your service:

    @Service({name: 'Test')
    class Test {
       	
    }

    When defined, Node Injection will use this property instead of Function.name.

  2. Disable function name mangling. For Webpack's UglifyJS plugin, this is how you do it:

    new webpack.optimize.UglifyJsPlugin({sourceMap: true, mangle: {keep_fnames: true}})

    The disadvantage of this approach is that code obfuscation will be reduced.

Injecting services

Constructor is used to emphasize that the given parameter must be a class. It is defined as:

interface Constructor {
	new (): any;
}

which simply represents a class object:

class MyClass {

}

and MyClass would be the argument.

Basic usage

Sometimes, you want to inject services in classes that aren't services themselves. You can use the @Inject() property decorator to this end.

class A {
	@Inject()
	private myService: MyService;
	
	constructor() {
		// this.myService...
	}
}

Working with interfaces

When a property type is an interface, you need to tell Node Injection which class to inject:

class A {
	@Inject(MyService)
	private myService: MyServiceInterface;
	
	constructor() {
		// this.myService...
	}
}

Contributing

Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.

Authors

See also the list of contributors who participated in this project.

License

This project is licensed under the MIT License - see the LICENSE.md file for details.