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

easy-injectionjs

v0.1.42

Published

A package that provides dependency injection using common design patterns as stereotypes. It easily injects depedencies in runtime and supports inheritance:

Downloads

4

Readme

easy-injectionJS

A package that provides dependency injection using common design patterns as stereotypes. It easily injects depedencies in runtime and supports inheritance:

There's no additional dependencies or containers needed to use the package. You can simply use it as follows:

npm i -S easy-injectionjs

Or

yarn add easy-injectionjs

Dependencies without inheritance:

import { Easy, EasyPrototype, EasySingleton } from 'easy-injectionjs';

// Creates a singleton instance of Movie class in runtime
@EasySingleton()
class Movie {
  constructor (private name: string, private ratings: number) {
    // Lets say that they just release the movie :D
    this.name = 'Black Panther';
    this.ratings = 9.0; // I really like that movie
  }

  public getName(): string {
    return this.name;
  }

  public getRatings(): number {
    return this.ratings;
  }

  public setName(v: string) {
    this.name = v;
  }

  public setRatings(v: number) {
    this.ratings = v;
  }
}

// Creates a multiple instances as needed in runtime
@EasyPrototype()
class Actor {
  @Easy()
  private movie: Movie;
  private name: string;

  constructor (name: string) {
    this.name = name;
  }

  public getMovieName(): string {
    return this.movie.getName();
  }

  public setMovieName(v: string) {
    this.movie.setName(v);
  }
}

let T_Challa = new Actor('Chadwick Boseman');
console.log(T_Challa.getMovieName());// Output is Black Panther
T_Challa.setMovieName('Black Panther II'); // Hopefully
console.log(T_Challa.getMovieName()); // Output is Black Panther II
let Erik_Killmonger = new Actor('Michael B Jordan');
console.log(Erik_Killmonger.getMovieName()) // // Output is Black Panther II

If the movie had the annotaion of EasyPrototype instead, Erik_Killmonger.getMovieName() will return Black Panther istead of Black Panther 2.

Interfaces and named dependencies example:

import { Easy, EasyPrototype, EasySingleton } from 'easy-injectionjs';

interface Show {
  getName(): string;
  getRatings(): number;
  setName(v: string);
  setRatings(v: number);
}

// Creates a singleton instance of Movie class in runtime
@EasySingleton('Movie')
class Movie implements Show {
  constructor (private name: string, private ratings: number) {
    // Lets say that they just release the movie :D
    this.name = 'Black Panther';
    this.ratings = 9.0; // I really like that movie
  }

  public getName(): string {
    return this.name;
  }

  public getRatings(): number {
    return this.ratings;
  }

  public setName(v: string) {
    this.name = v;
  }

  public setRatings(v: number) {
    this.ratings = v;
  }
}

// Creates a multiple instances as needed in runtime
@EasyPrototype()
class Actor {
  @Easy('Movie')
  private movie: Show;
  private name: string;

  constructor (name: string) {
    this.name = name;
  }

  public getMovieName(): string {
    return this.movie.getName();
  }

  public setMovieName(v: string) {
    this.movie.setName(v);
  }
}

let T_Challa = new Actor('Chadwick Boseman');
console.log(T_Challa.getMovieName());// Output is Black Panther
T_Challa.setMovieName('Black Panther II'); // Hopefully
console.log(T_Challa.getMovieName()); // Output is Black Panther II
let Erik_Killmonger = new Actor('Michael B Jordan');
console.log(Erik_Killmonger.getMovieName()) // // Output is Black Panther II

The package support inheritance even with abstract classes using the @EasyFactory decorator:

Example:

import { Easy, EasyFactory, EasyPrototype, EasySingleton } from 'easy-injectionjs';

@EasyFactory()
abstract class Show {
  public abstract getName(): string;
  public abstract getRatings(): number;
  public abstract setName(v: string);
  public abstract setRatings(v: number);
}

// Creates a singleton instance of Movie class in runtime
@EasySingleton()
class Movie extends Show {
  constructor (private name: string, private ratings: number) {
    super();
    // Lets say that they just release the movie :D
    this.name = 'Black Panther';
    this.ratings = 9.0; // I really like that movie
  }

  public getName(): string {
    return this.name;
  }

  public getRatings(): number {
    return this.ratings;
  }

  public setName(v: string) {
    this.name = v;
  }

  public setRatings(v: number) {
    this.ratings = v;
  }
}

// Creates a multiple instances as needed in runtime
@EasyPrototype()
class Actor {
  @Easy()
  private movie: Show;
  private name: string;

  constructor (name: string) {
    this.name = name;
  }

  public getMovieName(): string {
    return this.movie.getName();
  }

  public setMovieName(v: string) {
    this.movie.setName(v);
  }
}

let T_Challa = new Actor('Chadwick Boseman');
console.log(T_Challa.getMovieName());// Output is Black Panther
T_Challa.setMovieName('Black Panther II'); // Hopefully
console.log(T_Challa.getMovieName()); // Output is Black Panther II
let Erik_Killmonger = new Actor('Michael B Jordan');
console.log(Erik_Killmonger.getMovieName()) // // Output is Black Panther II

Both Iterfaces and abstract classes inheritance support naming to differentiate between the children dependencies and the names have to go into the @Easy decorator and have to match the names in the @EasyPrototype and @EasySingleton decorators. You can even name the @EasyFactory decorator if u have many abstract classes extending each others.

You can even not name anything and let the package figure out which dependencies as needed:

import { Easy, EasyFactory, EasyPrototype, EasySingleton } from 'easy-injectionjs';

@EasyFactory()
abstract class Person {
  abstract getName();
  abstract setName(v: string);
}

// @EasyObservable()
@EasySingleton()
class Somebody extends Person{
  // @Easy()
  constructor (private name: string) {
    super()
    this.name = 'Sal';
  }

  public getName() {
    return this.name;
  }
  public setName(v: string) {
    this.name = v;
  }
}

@EasyPrototype()
class Nobody extends Person{
  @Easy()
  somebody: Person;
  constructor () {
    super()
  }
  
  public getName() {
    return this.somebody.getName();
  }

  public setName(v: string) {
    this.somebody.setName(v);
  }
}

@EasyPrototype()
class Data {
  @Easy()
  somebody: Person;
  name: string;

  change(v: string) {
    this.somebody.setName(v);
  }

  getName(): string {
    return this.somebody.getName();
  }
}

let n = new Nobody();
console.log(n.getName()) // Prints Sal
n.setName('awesome');
console.log(n.getName())  // Prints awesome
let d = new Data()
console.log(d.getName())  // Prints awesome
d.change('Gelba')
console.log(n.getName())  // Prints Gelba
d.change('kaa')
console.log(n.getName())  // Prints Kaa

The "is" Keyword:

The "is" function is used to retrieve dependencies anywhere in the program. It can also be usint with constructor injection:

Example:

import { EasySingleton,
         EasyPrototype,
         is } import 'easy-injectionjs';

@EasySingleton()
class Somebody {
  // @Easy()
  constructor (private name: string) {
    this.name = 'Vladi';
  }

  public getName() {
    return this.name;
  }
  public setName(v: string) {
    this.name = v;
  }
}

@EasyPrototype()
class Awesome {
  private _name: string;
  constructor (someone: Somebody = is(Somebody)) {
    someone.setName('Sal')
    this._name = someone.getName();
    console.log(this._name);
  }
}

is(Awesome) // call returns an instance of Awesome

console.log(is(Somebody).getName()) // returns Sal since it is a singleton :D

The "Easily" Method:

The "Easily" is ideally used to define static constants or simple objects like:

import { Easily } from 'easy-injectionjs';

const config = {
  author: 'Sal'
}
Easily('config', config);

It requires a name to be injected. PS it can work for npm packages also, if imported like this: import * as smth from 'package'

@EasyPrototype()
class Nobody {
  @Easy('config')
  config: Object;
  constructor () {
    super()
  }
  
  public getName() {
    return this.somebody.getName();
  }
 
  public setName(v: string) {
    this.somebody.setName(v);
  }
}

A bit complicated example:

import {Easy, EasyPrototype, EasySingleton, EasyFactory, Easily, is} from 'easy-injectionjs';

Easily('config', {
  feeling: 'hungry'
})

@EasyFactory()
abstract class Person {
  abstract getName();
  abstract setName(v: string);
}

@EasySingleton()
class Somebody extends Person{
  // @Easy()
  constructor (private name: string) {
    super()
    this.name = 'Sal';
  }
 
  public getName() {
    return this.name;
  }
  public setName(v: string) {
    this.name = v;
  }
}
 
@EasyPrototype()
class Nobody extends Person{
  @Easy()
  somebody: Person;
  @Easy('config')
  config: Object;
  constructor () {
    super()
  }
  
  public getName() {
    return this.somebody.getName();
  }
 
  public setName(v: string) {
    this.somebody.setName(v);
  }
}

@EasyFactory()
abstract class Show {
  public abstract getName(): string;
  public abstract getRatings(): number;
  public abstract setName(v: string);
  public abstract setRatings(v: number);
}
 
// Creates a singleton instance of Movie class in runtime
@EasySingleton()
class Movie extends Show {
  constructor (private name: string, private ratings: number) {
    super();
    // Lets say that they just release the movie :D
    this.name = 'Black Panther';
    this.ratings = 9.0; // I really like that movie
  }
 
  public getName(): string {
    return this.name;
  }
 
  public getRatings(): number {
    return this.ratings;
  }
 
  public setName(v: string) {
    this.name = v;
  }
 
  public setRatings(v: number) {
    this.ratings = v;
  }
}
 
@EasySingleton()
class Data {
  @Easy()
  somebody: Person;
  name: string;
  @Easy()
  movie: Movie;
  change(v: string) {
    this.somebody.setName(v);
  }
 
  getName(): string {
    return this.somebody.getName();
  }
}
 
let n = new Nobody();
console.log(n)
console.log(n.getName()) // Prints Sal
n.setName('awesome');
console.log(n.getName())  // Prints awesome
let d = new Data()
console.log(d)
console.log(d.getName())  // Prints awesome
d.change('Gelba')
console.log(n.getName())  // Prints Gelba
d.change('kaa')
console.log(n.getName())

Even method injection is very easy using both "Easily", the decorators and "is". That makes dynamic injection very easy.

import { Easily } from 'easy-injectionjs';

Easily('Data', {
  name: 'Sal'
});

And somewhere in the program in another file:

import { is, Easily } from 'easy-injectionjs';

function modifyData(data: any = is('Data')) {
  data.name = 'I am Batman';
  // update it
  Easily('Data',data);
}

And maybe another class requires "Data":

import { EasyPrototype, Easy } from 'easy-injectionjs';
// why not :D
@EasyPrototype()
class Mule {
  @Easy('Data')
  private data:any;
}

If modifyData was called before Mule was used, the data name inside the property data of mule will change in runtime.