@searchfe/inject-js

A Dependency Injection library

Usage no npm install needed!

<script type="module">
  import searchfeInjectJs from 'https://cdn.skypack.dev/@searchfe/inject-js';
</script>

README

inject-js

Build Status semantic-release Coveralls

A tiny dependency Injection library for TypeScript. https://searchfe.github.io/inject-js/

Install

Can be installed via npm

npm install --save @searchfe/inject-js

inject-js uses Reflect Metadata to determine dependencies, so you need make sure your tsconfig.json contains:

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

And, you'll need a polyfill for the Reflect API, such as:

Usage

Following are some use cases, more details please refer to the API Reference.

@injectable

@injectable is used to decorate the Service class, so that its dependencies can be resolved by inject-js and it can be injected to other services.

// car.ts
import { injectable } from 'inject-js';
import { Wheel } from './wheel';

@injectable
export class Car {
    constructor(private wheel: Wheel) {}
}

// wheel.ts
import { injectable } from 'inject-js';

@injectable
export class Wheel {
    constructor() {}
}

// index.ts application entry
import { Container } from 'inject-js';
import { Car } from './car';
import { Wheel } from './wheel;

const di = new Container();
di.addService(Car);
di.addService(Wheel);
const car = di.create(Car);

@inject

@inject(token) is used to decorate a dependency (constructor argument) to specify which provider should be used. The token argument is the unique identifier of a Provider within the container. token is typically used for cases where there's no Service class actually defined, or Metadata API is not available.

import { inject } from 'inject-js';
import { Wheel } from './wheel';

@injectable
export class Car {
    constructor(@inject('Wheel') private wheel: Wheel) {}
}

// index.ts application entry
import { Container } from 'inject-js';
import { Car } from './car';
import { Wheel } from './wheel';

const di = new Container();
di.addService('Wheel', Wheel);
di.addService(Car);
const car = di.create(Car);

@service

If the container instance is available in the context where Services are defined, @service can be used as a shorthand of .addService():

const container = new Container();

@service(container)
class FooService {}

// Equivalent to:

const container = new Container();

@injectable
class FooService {}

container.addService(FooService)

Container

The Container class maintains a set of Providers and the corresponding Tokens. There're several ways to register Providers:

  • .addProvider(): register a factory class with a .create(): Service method. All other ways are implemented using .addProvider() internally.
  • .addFactory(): register a factory function which returns a Service instance.
  • .addService(): register a concrete Service class.
  • .addValue(): register a value.