Giter Club home page Giter Club logo

di's Introduction

Test Coverage-shield-badge-1

DI - Dependency Injection

A very simple & lean dependency injection container for Typescript.

Key features

  • Decorator to Inject services
  • Light weight & simple to use
  • No dependencies

How to use

  1. Install the module

npm install @thenja/di --save

  1. Import and use the module
import { DI, IDIProvider } from '@thenja/di';

// our singleton service
class UtilityService {}

class User {
  @DI.Inject(UtilityService)
  private utilSrv: UtilityService;
}

Examples

Inject using a factory

import { DI, IDIProvider } from '@thenja/di';

let env = 'dev';

abstract class BaseStorageService {
  abstract name: string;
}
class FileStorageService extends BaseStorageService {
  name = 'file-storage';
}
class MemoryStorageService extends BaseStorageService {
  name = 'memory-storage';
}

const storageFactory: IDIProvider = {
  provide: BaseStorageService,
  useFactory: () => {
    if (env === 'dev') return new MemoryStorageService();
    return new FileStorageService();
  }
};

class MyTest {
  @DI.Inject(storageFactory)
  public storageSrv: BaseStorageService;
}

Inject using a different class

import { DI, IDIProvider } from '@thenja/di';

class UserModel { name = 'user'; }
class MockUserModel { name = 'mock-user'; }

const userProvider: IDIProvider = {
  provide: UserModel,
  useClass: MockUserModel
};

class MyTest {
  @DI.Inject(userProvider)
  public user: UserModel;
}

Dealing with models

Models are usually not singletons, however, we should still use dependency injection via the factory pattern to create the new model instances.

// BAD

class UserSettingsModel {}

class UserModel {
  private settings: UserSettingsModel;

  constructor() {
    // makes it hard to mock settings, we should be using dependency injection
    this.settings = new UserSettingsModel();
  }
}

// BETTER

class UserSettingsModel {}

class UserModel {
  constructor(private settings: UserSettingsModel) {}
}

class UserModelFactory {
  create(): UserModel {
    return new UserModel(new UserSettingsModel());
  }
}

class UserService {
  @DI.Inject(UserModelFactory)
  private userModelFactory: UserModelFactory;

  getUser(): UserModel {
    // we can now mock the UserModelFactory
    return this.userModelFactory.create();
  }
}

Methods / API

@DI.Inject(service: any|IDIProvider)

Inject a singleton service into a class. You can either pass in a class object, or a IDIProvider object (see examples above).

@DI.override(service: any|IDIProvider, dependencyInstance: any)

Override a service. Useful for mocking services.

@DI.getService(service: any|IDIProvider): any

Get the service instance that is stored inside the dependency container.

@DI.clear()

Clear the dependency container.

@DI.getContainer(): { [key: string]: any }

Get the dependency container. Basically, the container is a json object with the key being the name of the service (randomly generated) and the value being the instance of the service.

@DI.getContainerName(service: any|IDIProvider): string

Get the name used in the dependency container for a particular service.

Development

npm run init - Setup the app for development (run once after cloning)

npm run dev - Run this command when you want to work on this app. It will compile typescript, run tests and watch for file changes.

Distribution

npm run build -- -v <version> - Create a distribution build of the app.

-v (version) - [Optional] Either "patch", "minor" or "major". Increase the version number in the package.json file.

The build command creates a /compiled directory which has all the javascript compiled code and typescript definitions. As well, a /dist directory is created that contains a minified javascript file.

Testing

Tests are automatically ran when you do a build.

npm run test - Run the tests. The tests will be ran in a nodejs environment. You can run the tests in a browser environment by opening the file /spec/in-browser/SpecRunner.html.

License

MIT © Nathan Anderson

di's People

Contributors

nathan-andosen avatar nathan-anderson avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.