1.1.0 • Published 6 years ago

express-locator v1.1.0

Weekly downloads
1
License
MIT
Repository
github
Last release
6 years ago

Express Locator

GitHub last commit Build Status Coverage Status

GitHub package version license

npm npm downloads

GitHub repo size in bytes npm bundle size (minified)

A service locator/Dependency injector for Node apps.

npm install express-locator

OR

yarn add express-locator

Usage

Initialising locator

import expressLocator from 'express-locator';

//OR

const expressLocator = require('express-locator');

expressLocator.config(config, ...dependencies);

Dependency Registration Object

Each dependency registration should be either a string or an object. Multiple dependencies can be passed as either an array or additional arguments.

type toRegisterType =
  | {
      name?: string,
      // the name of your dependency
      dependencies?: Array<string>,
      // an array of dependency names. Will be automatically assigned to 'this'
      // when extending the Instance class, otherwise passed as the second
      // paramater
      config?: boolean,
      // receive the entire config object in your construct function
      construct?: Function | Class<any> | string,
      // the function or class to be called to construct your dependency, or the
      // name of the node_module dependency to require()
      invoke?: boolean,
      // if true, caches the dependency immediately after registering all passed
      // dependencies
      instance?: boolean,
      // if true, will call the construct with new
      [key: string]: Function | Class<any> | string,
      // rather than using the props 'name' and 'construct', you can use
      // { dependencyName : construct }, where the key will be used as the
      // dependency name and the value as the construct function | class | string
    }
  | string
  // the name of the node_module dependency to require(). Will be registered
  // under that name
  | Array<toRegisterType>;
// an array of either of the above

If the provided construct is a Function or Class (Class must either extend the provided Instance class or the registration object must include instance = true), it will be called with the following arguments

/**
 * @description configures and returns a dependency or class
 * @param {{ ControlledError, config, expressLocator }} props an object containing an extended
 * Error object which includes an isControlled = true, the locator instance and
 * the relevant config (or entire config object if config = true was included
 * in the registration object)
 * @param {[string]} dependencies the array of dependency names you provided in
 * your registration object
 */

function dependencyConfigurator(props, dependencies) {
  //do stuff and return dependency
}

// or

class Dependency {
  constructor(props, dependencies) {
    // do stuff to initiate class
  }
}

// or

import expressLocator from 'express-locator';

const Instance = expressLocator.get('instance');

class Dependency extends Instance {
  someMethod() {
    this.expressLocator;
    // locator instance available
    this.ControlledError;
    // custom error constructor available
    this.config;
    // relevant config available
    this.someDependency;
    // dependencies specified in registration object available
  }
}

Dependencies can be registered in two ways.

// passed as additional arguments to the config function
expressLocator.config(config, ...dependencies);

// OR calling expressLocator.register directly

expressLocator.register(...dependencies);

Configuration Object

your config is simply an object with keys that match the dependency you want to recieve that config in their construct function.

for example

const config = {
  server: {
    port: process.env.PORT || 8080,
  },
};

// elsewhere in your serverConstruct function

const serverConstruct = ({ expressLocator, config }) => {
  const server = expressLocator.get('http').createServer(expressLocator.get('app'));

  server.listen(config.port);

  return server;
};

Retrieving a Dependency

Be careful to not create a circular dependency in your construct functions. Having two contruct functions retrieve each other will never resolve, as the dependency will only be cached once the construct function returns a value.

import expressLocator from 'express-locator'; //if not within a construct

const dependencyName = expressLocator.get('dependencyName');

// OR if the dependency is an object you can retrieve a nested property

const property = expressLocator.get('dependencyName.nested.property');

Explanation

Express Locator is a simple Dependency Injector and Manager. By registering your dependencies, it will store a single intance and return that same instance every time it is retrieved.

While not exactly necessary in Node, it is a syntactical abstraction of dependency management which can clean up the need for the first view of your code to be a list of require()'s or imports .

In future there will also be statistical logging added so you can check dependencies which are being underutilised.

TODO

  • Add option to log dependency usage statistics to determine unused/underutilised dependencies
  • Add option to automatically register all dependencies in package.json
  • config function to return a promise
  • Add option to use asyncronous get function and support import() syntax in addition to require()
  • finish JSDocs for Locator
1.2.0-rc.4

6 years ago

1.2.0-rc.1

6 years ago

1.2.0-beta.13

6 years ago

1.2.0-beta.12

6 years ago

1.2.0-beta.11

6 years ago

1.2.0-beta.10

6 years ago

1.2.0-beta.9

6 years ago

1.1.0

6 years ago

1.0.1

6 years ago

1.0.1-rc.0

6 years ago

1.0.0

6 years ago

0.3.4-2

6 years ago

0.3.4-0

6 years ago

0.3.3

6 years ago

0.3.2

6 years ago

0.3.1

6 years ago

0.3.0

6 years ago

0.2.9-0

6 years ago

0.2.8-0

6 years ago

0.2.7-0

6 years ago

0.2.6-0

6 years ago

0.2.1-0

6 years ago

0.2.0

6 years ago

0.1.1

6 years ago

0.1.0

6 years ago

0.0.9

6 years ago

0.0.8

6 years ago

0.0.7

6 years ago

0.0.6

6 years ago

0.0.5

6 years ago

0.0.4

6 years ago

0.0.2

6 years ago

0.0.1

6 years ago