Functional dependency injection container for javascript


Keywords
dependency-injection, functional-programming, inversion-of-control, javascript, nodejs, register-dependency
License
MIT
Install
npm install intify@1.0.0-beta1

Documentation

Intify

Declarative lightweight IoC (inversion of control) container for javascript, built for functional programming style.

Intify allows you to keep all of your dependencies in one place and lazy load them on demand.

Motivation

When you working in functional programming style you want to control every single piece of your app. And if you use Dependency injection and Inversion of control design patterns in your workflow then you have many different dependencies linked between your functions. And it becomes a pain to reach them all and keeping in mind where from each dependency comes in.

That's why I started to build very simple and lightweight injection container. I want to create handy workflow to myself.

Hope you will find it useful too.


Installation

yarn add intify

or

npm install intify

Features

  1. Lightweight ~ 4kb
  2. Built using typescript
  3. Very intuitive api

How it works

General scheme looks like this: General scheme

And flow is simple:

  1. Register all of the dependencies
  2. Wrap your functions with withDeps higher order function
  3. Intify will take over the rest

Usage

Import

import { store, withDeps } from 'intify';

General usage

Each function with dependencies should be curried with "deps" object. For example:

const logMessage = deps =>
  message => deps.log(message);

For simplier syntax you can use object destructuring:

const logMessage = ({ log }) =>
  message => log(message);

Register dependencies

For register any dependency you have to call .register() method on store object:

import { store } from 'intify';
store.register({ dependency });

Injecting dependecies

.widthDeps() is higher order function which returns wrapped function with provided dependencies.

import { withDeps } from 'intify';
const logMessage = deps =>
  message => deps.log(message);
export default withDeps(logMessage);

Examples

Usage example

// logMessage.js
import { withDeps } from 'intify';
export const logMessage = ({ log }) =>
  message => log(message);
export default withDeps(logMessage);

// index.js
import { store } from 'intify';
import log from './logger';
store.register({ log });

// somewhere else
import logMessage from './logMessage';
logMessage(myValue);

Test example

// utility.spec.js
import { utility } from './utility';

test('should works', () => {
  const mockDatabase = jest.fn();
  utility({ database: mockDatabase })(mockValue);
  expect(mockDatabase).toBeCalled();
});

API

Store

Store with all dependencies. Currently allows to keep only 1 store at time.

Example:

import { store } from 'intify';

store.register({ database });

store.getDeps :: () -> Object

Returns object with all registered dependencies

store.subscribe :: (next) -> Observer

Experimental feature

Require "next" function which will be triggered each time when any dependency will be called.

Next will be called with object:

{
  fn, // called function
  name, // called function's name
  args // arguments provided to called function
}

Example:

import { store } from 'intify';
const observer = store.subscribe(console.log);
// to unsubscribe just call
observer.unsubscribe();

store.unsubscribe :: () -> Void

Remove all listeners.

withDeps :: (Object) => (Function) => Function

Wrap target function with dependency store

Example:

import { withDeps } from 'intify';
const makeAddValueToDatabase = ({ database }) =>
  function addValueToDatabase(newValue) {
    return database.add(newValue);
  }

export default withDeps(makeAddValueToDatabase); // = addValueToDatabase - with provided dependencies

Dependencies

Contributing