1.0.12 • Published 5 years ago

smart-factory v1.0.12

Weekly downloads
2
License
ISC
Repository
github
Last release
5 years ago

smart-factory

npm version

Simple but powerful, functional-programming ready Dependency Injector/Container library for node.js.

dependency injection library for not only classes but also functions, strings, numbers, ... and all objects in the world.

features

  • simple syntax, easy to use
  • functional-programming ready
  • lightweight
  • built-in typescript supports
  • supports lazy-instantiation

installation

npm i smart-factory

simple usage

javascript + es6

const { init, injectable, resolve } = require('smart-factory');

// module names
const ModuleNames = {
  MSG_PROVIDER: 'MSG_PROVIDER',
  MSG_PRINTER: 'MSG_PRINTER',
  GREETER: 'GREETER'
};

// regiser message provider function to container
injectable(ModuleNames.MSG_PROVIDER,
  [], 
  () =>
    new Promise((resolve) => {
      const toBeRegistered = (lang) => { // msgProvider function.
        if (lang === 'en') return 'HELLO!';
        else if (lang === 'ko') return '안녕하세요!';
        else if (lang === 'es') return 'HOLA!';
        return 'UNKNOWN';
      };
      resolve(toBeRegistered);
    }));

// register message printer function to container
injectable(ModuleNames.MSG_PRINTER,
  [], 
  () => 
    new Promise((resolve) => {
      const toBeRegistered = (msg) => console.log(msg); // msgPrinter function
      resolve(toBeRegistered);
    }));

// register greeter function to container.
injectable(ModuleNames.GREETER,
  [ModuleNames.MSG_PROVIDER, ModuleNames.MSG_PRINTER], // required dependencies
  (provider, printer) => // dependencies which injected from container
    new Promise((resolve) => {
      const toBeRegistered = (lang) => { // greeter function.
        printer(provider(lang));
      };
      resolve(toBeRegistered);
    }));

(() => {
  init() // awaiting container ready
    .then(() => {
      const greet = resolve(ModuleNames.GREETER); // injects greeter function from container.
      greet('en'); // HELLO!
    });
})();

typescript + es2015

import { init, injectable, resolve } from 'smart-factory';

export enum Modules {
  HELLO_FUNC = 'HELLO_FUNC',
  MSG_PROVIDER = 'MSG_PROVIDER',
  MSG_PRINTER = 'MSG_PRINTER'
}

export type MsgProvider = (lang: string) => string;
export type MsgPrinter = (msg: string) => void;
export type HelloFunction = (lang: string) => void;

injectable(
  Modules.MSG_PROVIDER, // module name
  [], // dependencies
  async (): Promise<MsgProvider> =>
    (lang: string): string => {
      if (lang === 'en') return 'HELLO!';
      else if (lang === 'ko') return '안녕하세요!';
      else if (lang === 'es') return 'HOLA!';
      return 'UNKNOWN';
    });

injectable(
  Modules.MSG_PRINTER,
  [],
  async () : Promise<MsgPrinter> =>
    (msg: string) => console.log(msg);

injectable(
   Modules.HELLO_FUNC,
   [ Modules.MSG_PROVIDER, Modules.MSG_PRINTER ], // has dependencies to MsgProvider, MsgPrinter
   async (provider: MsgProvider, printer: MsgPrinter): HelloFunction =>
     (lang: string) => {
       printer(provider(lang));
     });

(async () => {
  await init();

  const helloFunc = resolve<HelloFunction>(Modules.HELLO_FUNC);
  helloFunc('es'); // HOLA!
})();

API reference

async init(opts?: ContainerOptions): Promise\

initialize container. after init() executed, you can retreive a modules from container.

type ContainerOptions

keymandantorydefaultdescription
debug?: booleannofalseshow container logs. for debug purpose.
includes?: string[]nonullspecify path for modules which calls injectable().
excludes?: string[]nonullspecify path for exceptional modules.

example

(async () => {
  await init({
    debug: true,
    includes: [`${__dirname}/**/*.ts`]
  });
})();

injectable(key: string, deps: string[], instantiator: Instantiator): void

register modules to container. the dependencies deps[] will be injeted before the module instantiated.

after all dependencies meets requirements, the modules will be instantiated and registered to container with name key.

the instantiator is your async function that preparing instance from given dependencies deps[].

example

type Coffee = {
  bean: CoffeeBean;
  water: Water;
  sugar: Sugar;
};
type CoffeeMaker = () => Coffee;

injectable(
  'COFFEE_MAKER', // module name
  [ 'COFFEE_BEAN', 'WATER', 'SUGAR' ], // required dependencies
  async (bean, water, sugar): Promise<CoffeeMaker> => // the "Instantiator": returns coffeeMaker function. 
    () => { // coffeeMaker function
      return {
        bean, water, sugar
      }
    }
);

resolve\(key: string): \

resolves module from container. with typescript, you can specify type.

example

(async () => {
  const makeCoffee = await <CoffeeMaker>resolve('COFFEE_MAKER');
  const coffee = makeCoffee();
  console.log(coffee); // { bean, water, sugar }!
})();

set\(key: string, instance: T): void

replace an instance in container with given key and instance. you can use this feature in the test codes.

(async () => {
  injectable('A', [], async () => 10);
  await init(); // container initialized.

  const value = <number>resolve('A');
  console.log(value); // "10"

  set('A', 20);
  const valueAfterSet = <number>resolve('A');
  console.log(valueAfterSet); // "20"
})();

clear(): void

clear all instances in container

(async () => {
  injectable('A', [], async () => 10);
  await init(); // container initialized.

  const value = <number>resolve('A');
  console.log(value); // "10"

  clear(); // nothing in container.
})();

More complicated examples

There are a more complicated examples that using smart-factory. you can learn how to manage complicated dependencies (ex: configuration, database, models..) for complicated application with the smart-factory.

  • Chatpot-Room-Server
    • chatting-room server written with Typescript, smart-factory
    • configurations, mysql, models, api endpoints
    • shows handling modules names and types with typescript way.
1.0.12

5 years ago

1.0.11

5 years ago

1.0.10

5 years ago

1.0.9

5 years ago

1.0.8

5 years ago

1.0.7

5 years ago

1.0.6

5 years ago

1.0.5

5 years ago

1.0.4

5 years ago

1.0.3

5 years ago

1.0.2

5 years ago

1.0.1

5 years ago

1.0.0

5 years ago