Skip to content
/ dicoi Public

A simple Dependency injection / Inversion of Control Container example in Typescript

Notifications You must be signed in to change notification settings

ishabo/dicoi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DiCoI - DI/IoC Container

DiCoI is a simple Dependency injection / Inversion of Control Container example in Typescript that enables developers handle automatic dependency injection.

Installation

Using npm:

$ npm install dicoi

Using yarn:

$ yarn add dicoi

Example

Lets suppose a RatesService that connects to an API to get currency rates and logs results. It depends on ApiService and Logger. ApiService also depends on Logger and also requires a param. To automatically initialize RatesService with those dependencies, we'd like to be able to do:

import { Container } from 'dicoi';

const container = new Container();
const rates = container
  .inject({ ref: Logger, source: Logger, type: 'class' })
  .and({
    ref: BASE_URL,
    source: 'https://api.exchangeratesapi.io',
    type: 'param'
  })
  .and({ ref: ApiService, source: ApiService, type: 'class' })
  .into(RatesService);

rates.getRate('USD', ['GBP', 'EUR']).then(console.log);

DiCoI gives us a Container that will handle those dependenies for us. It has declarative methods that enable us to inject(DEPENDENCY_PARAM_OBJET).and(DEPENDENCY_CLASS_OBJET).into(MAIN_CLASS)

For this to work, you'll need to decorate RatesService and ApiService with @Injectable decorator, and any dependency (non-class) param must be decorated with @Inject decorator.

import { Container, Injectable, Inject, InjectableRef } from 'dicoi';

const BASE_URL = new InjectableRef('BASE_URL');

export class Logger {
  public log(...args: any[]) {
    console.log('[log]', ...args);
  }
}

@Injectable()
class ApiService {
  constructor(
    @Inject(BASE_URL) private baseUrl: string,
    private logger: Logger
  ) {
    this.logger.log('ApiService initialized');
  }

  async getData(endpoint: string) {
    const response = await fetch(`${this.baseUrl}/${endpoint}`);
    return await response.json();
  }
}

@Injectable()
class RatesService {
  constructor(
    private readonly api: ApiService,
    private readonly logger: Logger
  ) {
    this.logger.log('Launching rates service');
  }
  async getRate(base: string, symbols: string[]) {
    return await this.api.getData(
      `latest?base=${base}&symbols=${symbols.join(',')}`
    );
  }
}

NOTE: that Logger class does not need any decorator, because we do not need to inject anything into it.

You can view this working example in this demo

About

A simple Dependency injection / Inversion of Control Container example in Typescript

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published