A special thanks to Symfony which was a great inspiration and example for this project.
The Node Dependency Injection component allows you to standardize and centralize the way objects are constructed in your application.
npm install --save node-dependency-injectionImagine you have a Mailer class like this:
// services/Mailer.js
export default class Mailer {
  /**
   * @param {ExampleService} exampleService
   */
  constructor(exampleService) {
    this._exampleService = exampleService;
  }
  ...
}You can register this in the container as a service:
import {ContainerBuilder} from 'node-dependency-injection'
import Mailer from './services/Mailer'
import ExampleService from './services/ExampleService'
let container = new ContainerBuilder()
container
  .register('service.example', ExampleService)
container
  .register('service.mailer', Mailer)
  .addArgument('service.example')And get services from your container
const mailer = container.get('service.mailer')import {ContainerBuilder, Autowire} from 'node-dependency-injection'
const container = new ContainerBuilder(
  false, 
  '/path/to/src'
)
const autowire = new Autowire(container)
await autowire.process()or from yaml-json-js configuration
# /path/to/services.yml
services:
  _defaults:
    autowire: true
    rootDir:  "/path/to/src"You can also get a service from a class definition
import SomeService from '@src/service/SomeService'
container.get(SomeService)If you are transpiling your Typescript may you need to dump the some kind of service configuration file.
import {ContainerBuilder, Autowire, ServiceFile} from 'node-dependency-injection'
const container = new ContainerBuilder(
  false, 
  '/path/to/src'
)
const autowire = new Autowire(container)
autowire.serviceFile = new ServiceFile('/some/path/to/dist/services.yaml')
await autowire.process()My proposal for load configuration file in a production environment with transpiling/babel compilation:
if (process.env.NODE_ENV === 'dev') {
  this._container = new ContainerBuilder(false, '/src');
  this._autowire = new Autowire(this._container);
  this._autowire.serviceFile = new ServiceFile('/some/path/to/dist/services.yaml');
  await this._autowire.process();
} else {
  this._container = new ContainerBuilder(false, '/dist');
  this._loader = new YamlFileLoader(this._container);
  await this._loader.load('/some/path/to/dist/services.yaml');
}
await this._container.compile();You can also use configuration files to improve your service configuration
# /path/to/file.yml
services:
  service.example:
    class: 'services/ExampleService'
  service.mailer:
    class: 'services/Mailer'
    arguments: ['@service.example']import {ContainerBuilder, YamlFileLoader} from 'node-dependency-injection'
let container = new ContainerBuilder()
let loader = new YamlFileLoader(container)
await loader.load('/path/to/file.yml')And get services from your container easily
...
const mailer = container.get('service.mailer')- Autowire for TypeScript
- Configuration files with JS, YAML or JSON.
- Multiple configuration files
- Custom relative service directory
- Compiling container
- Custom compiler pass
- Change definition behaviour
 
- Using a factory to create services
- Nullable Dependencies
- Public or private services
- Service Aliasing
- Service Tagging
- Parameters Injection
- Lazy Services
- Deprecate Services
- Decorate Services
- Synthetic Services
- Non Shared Services
- Parent and Abstract Services
- Custom Logger
- Container as Service
Please read full documentation
If you are using expressJS and you like Node Dependency Injection Framework then I strongly recommend
you to use the node-dependency-injection-express-middleware package.
That gives you the possibility to retrieve the container from the request.
npm install --save node-dependency-injection-express-middlewareimport NDIMiddleware from 'node-dependency-injection-express-middleware'
import express from 'express'
const app = express()
const options = {serviceFilePath: 'some/path/to/config.yml'}
app.use(new NDIMiddleware(options).middleware())If you are using typescript and you like Node Dependency Injection Framework then typing are now provided at node-dependency-injection so
you do not have to create custom typing anymore.
npm install --save node-dependency-injectionimport { ContainerBuilder } from 'node-dependency-injection'
import MongoClient from './services/MongoClient'
import { Env } from './EnvType'
export async function boot(container = new ContainerBuilder(), env: Env) {
    container.register('Service.MongoClient', MongoClient).addArgument({
        host: env.HOST,
        port: env.PORT,
    })
}