{"id":14384459,"url":"https://github.com/di-ninja/di-ninja","last_synced_at":"2025-08-23T17:32:18.018Z","repository":{"id":27554407,"uuid":"114372625","full_name":"di-ninja/di-ninja","owner":"di-ninja","description":"The Dependency Injection Framework for JavaScript NodeJS and Browser - really made for Composition Root","archived":false,"fork":false,"pushed_at":"2023-03-01T12:09:13.000Z","size":2662,"stargazers_count":66,"open_issues_count":11,"forks_count":3,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-12-02T06:20:21.800Z","etag":null,"topics":["babel","best-practices","composition-root","decorator","dependency","dependency-injection","dependency-injection-container","di","dic","factory","framework","injection","inversion-of-control","ioc","node","oop","react-native","strategy","webpack"],"latest_commit_sha":null,"homepage":"https://di-ninja.github.io/di-ninja/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/di-ninja.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-12-15T13:16:54.000Z","updated_at":"2024-10-03T13:36:15.000Z","dependencies_parsed_at":"2024-01-14T20:16:26.625Z","dependency_job_id":"c4f357d2-f902-42f2-8e74-12f64b868b7e","html_url":"https://github.com/di-ninja/di-ninja","commit_stats":null,"previous_names":[],"tags_count":45,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/di-ninja%2Fdi-ninja","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/di-ninja%2Fdi-ninja/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/di-ninja%2Fdi-ninja/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/di-ninja%2Fdi-ninja/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/di-ninja","download_url":"https://codeload.github.com/di-ninja/di-ninja/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230716524,"owners_count":18269781,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["babel","best-practices","composition-root","decorator","dependency","dependency-injection","dependency-injection-container","di","dic","factory","framework","injection","inversion-of-control","ioc","node","oop","react-native","strategy","webpack"],"created_at":"2024-08-28T18:01:24.358Z","updated_at":"2025-08-23T17:32:18.006Z","avatar_url":"https://github.com/di-ninja.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# this project is not maintained anymore, We recommend to use lightweight and powerfull [nctx](https://github.com/devthefuture-org/nctx)\n\n# Di-Ninja [![Di-Ninja ICON](https://raw.githubusercontent.com/di-ninja/di-ninja/master/icon/icon.png)](https://github.com/di-ninja/di-ninja#)\n\n[![npm version](https://badge.fury.io/js/di-ninja.svg)](https://www.npmjs.com/package/di-ninja)\n[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)\n[![Unix Build](https://travis-ci.org/di-ninja/di-ninja.svg?branch=master)](https://travis-ci.org/di-ninja/di-ninja)\n[![Windows Build](https://ci.appveyor.com/api/projects/status/github/di-ninja/di-ninja?branch=master\u0026svg=true)](https://ci.appveyor.com/project/surikat/di-ninja/branch/master)\n[![Dependencies](https://david-dm.org/di-ninja/di-ninja.svg)](https://david-dm.org/di-ninja/di-ninja#info=dependencies)\n[![devDependencies](https://david-dm.org/di-ninja/di-ninja/dev-status.svg)](https://david-dm.org/di-ninja/di-ninja/#info=devDependencies)\n[![Known Vulnerabilities](https://snyk.io/test/github/di-ninja/di-ninja/badge.svg)](https://snyk.io/test/github/di-ninja/di-ninja)\n[![NPM Status](http://img.shields.io/npm/dm/di-ninja.svg?style=flat)](https://www.npmjs.com/package/di-ninja)\n\nThe Dependency-Injection Framework for JavaScript NodeJS and Browser.\n\n## Installation\n```\n$ npm i di-ninja\n```\n\n## Goals\n  * Implement [IoC](https://en.wikipedia.org/wiki/Inversion_of_control) by [Composition-Root](http://blog.ploeh.dk/2011/07/28/CompositionRoot/) design pattern, allowing to keep all things decoupled and to wire application components and config at one unique root place.\n\n  * Replace the singleton anti-pattern with dependency-injection by refacto export of instances to export of classes and factories.\n  \n  * Get a pure JavaScript non-dogmatic cross-transpiller [Dependency-Injection](https://en.wikipedia.org/wiki/Dependency_injection) framework.\n\n  * Encourage adherence to the best practices of Object Oriented design\n  ( [SOLID](https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)),\n  [IoC](https://en.wikipedia.org/wiki/Inversion_of_control),\n  [Dependency-Injection](https://en.wikipedia.org/wiki/Dependency_injection),\n  [Composition-Root](http://blog.ploeh.dk/2011/07/28/CompositionRoot/),\n  [Strategy](https://en.wikipedia.org/wiki/Strategy_pattern) ...).\n  \n  * Improve code testability.\n  \n  * Extend the Art of JavaScript development.\n\n## Paradigm - Dependency Injection vs Modules\n\nWhy to not simply just use *ES6 import* or *CommonJS require* ?  \nDi-Ninja don't pretend to replace these features, that would be useless.  \nUsing import/export for getting class or factory function is the good way to use it, that's why it was made for.  \nBut using modules to export [singleton](https://en.wikipedia.org/wiki/Singleton_pattern) is an [anti-pattern](https://en.wikipedia.org/wiki/Anti-pattern)\nand leading to [global state](https://softwareengineering.stackexchange.com/questions/148108/why-is-global-state-so-evil).\nIt predisposes application to more need for refacto in future, less testability (unable without hack).  \nHow to know when to use *dependency injection* over *import/require*, it's very simple:  \nwhen it's about the implementation, always use dependency injection, even if it's a factory that is exported,\nelse if it's not an instance but a stateless input/output function with a general purpose,\nusually coming from a third party library, you can use import. In case of doubt always use dependency injection !\n\n\n## Documentation\n\n### Summary\n\n1. [Getting Started](#1-getting-started)\n\n2. [Dependencies declarations approaches](#2-dependencies-declarations-approaches)\n    1. [Composition Root](#21-composition-root)\n    2. [Decorator injection approach](#22-decorator-injection-approach)\n        1. [abstract class](#221-abstract-class)\n        2. [reference class](#222-reference-class)\n\n3. [Dependencies Resolution](#3-dependencies-resolution)\n    1. [Recursive classes or factories](#31-recursive-classes-or-factories)\n    2. [Recursive params](#32-recursive-params)\n    3. [Types of params](#33-types-of-params)\n        1. [interface](#331-interface)\n        2. [value](#332-value)\n        3. [factory](#333-factory)\n        5. [valueFactory](#334-valuefactory)\n        6. [classFactory](#335-classfactory)\n        4. [require](#336-require)\n\n4. [Rules](#4-rules)\n  \n    1. [dependencies](#41-dependencies)\n        1. [params](#411-params)\n        2. [calls](#412-calls)\n        3. [lazyCalls](#413-lazycalls)\n  \n    2. [instantiation](#42-instantiation)\n        1. [classDef](#421-classdef)\n        2. [instanceOf](#422-instanceof)\n        3. [substitutions](#423-substitutions)\n  \n    3. [single instance](#43-single-instance)\n        1. [shared](#431-shared)\n        2. [singleton](#432-singleton)\n        3. [sharedInTree](#433-sharedintree)\n  \n    4. [rule inheritance](#44-rule-inheritance)\n        1. [inheritInstanceOf](#441-inheritinstanceof)\n        2. [inheritPrototype](#442-inheritprototype)\n        3. [inheritMixins](#443-inheritmixins)\n        4. [decorator](#444-decorator)\n\n    5. [asynchrone dependencies resolution](#45-asynchrone-dependencies-resolution)\n        1. [asyncResolve](#451-asyncresolve)\n        2. [asyncCallsSerie](#452-asynccallsserie)\n        3. [asyncCallsParamsSerie](#453-asynccallsparamsserie)\n    \n    6. [dependency file location](#46-dependency-file-location)\n        1. [autoload](#461-autoload)\n        2. [path](#462-path)\n\n\n5. [Container](#5-container)\n\n    1. [rules](#51-rules)\n    2. [rulesDefault](#52-rulesdefault)\n  \n    3. [dependencies](#53-dependencies)\n    4. [autoloadPathResolver](#54-autoloadpathresolver)\n    5. [autoloadExtensions](#55-autoloadextensions)\n    6. [autoloadFailOnMissingFile](#56-autoloadfailonmissingfile)\n  \n    7. [defaultVar](#57-defaultvar)\n    8. [defaultRuleVar](#58-defaultrulevar)\n    9. [defaultDecoratorVar](#59-defaultdecoratorvar)\n    10. [defaultArgsVar](#510-defaultargsvar)\n  \n    11. [defaultFactory](#511-defaultfactory)\n    12. [defaultFunctionWrapper](#512-defaultfunctionwrapper)\n  \n    13. [promiseFactory](#513-promisefactory)\n    14. [promiseInterfaces](#514-promiseinterfaces)\n  \n    15. [interfacePrototype](#515-interfaceprototype)\n    16. [interfaceTypeCheck](#516-interfacetypecheck)\n  \n    17. [globalKey](#517-globalkey)\n  \n    18. [ruleCache](#518-rulecache)\n    19. [polyfillRequireContext](#519-polyfillrequirecontext)\n\n6. [Examples](#6-examples)\n\n### 1. Getting Started\n```javascript\nimport container from 'di-ninja'\n\nconst di = container()\n\ndi.addRules(rules)\n\ndi.get('MyClassName')\n```\n\n\n### 2. Dependencies declarations approaches\n\nTo define dependencies, you can use [Composition-Root](#21-composition-root) or [Decorator injection approach](#22-decorator-injection-approach) for each components individually.  \nDifferents approaches can be used for differents methods injections on same component.  \nDependencies definition can be overrided, the last call of addRule or @di decorator will take precedence.\n\n#### 2.1 Composition-Root\n\nThe Composition Root is the highest level of your application, the top overlay.  \nIt's here that you will configure many rules for your components and wire them together.  \nUsing only the Composition Root design pattern has the advantage to let your components totaly unopinionated,\nall your classes and factories can keep uncoupled from the dependency injector (di-ninja).\n\nexample with ES6 class syntax\n```javascript\nclass A{\n  constructor(b){\n    this.b = b\n  }\n}\nclass B{\n  constructor(){\n    this.foo = bar\n  }\n}\n\ndi.addRules({\n  'A': {\n    classDef: A,\n    params: [ 'B' ],\n  },\n  'B': {\n    classDef: B,\n  },\n}\n})\n\ndi.get('A')\n```\n\nexample with function as constructor or factory\n```javascript\n\n//function as a constructor\nfunction A(b){\n  this.b = b\n}\n\n//function as a factory\nfunction B(){\n  const object = { foo: 'bar' }\n  \n  // if we return an object or other value than undefined,\n  // this function will be treated by javascript as a factory\n  \n  return object\n}\n\ndi.addRules({\n  'A': {\n    classDef: A,\n    params: [ 'B' ],\n  },\n  'B': {\n    classDef: B,\n  },\n})\n\ndi.get('A')\n```\n\n\n#### 2.2 Decorator injection approach\n\nThe Decorator injection approach let your components define their own dependencies.  \nThese dependencies declarations can rely on container level defined abstractions (recommanded),\nor on direct class or factory definition.  \nIt can be used in addition to the Composition-Root and replace the rule's key [`params`](#411-params) and also the parameters of call argument for rule's key [`calls`](#412-calls) and [`lazyCalls`](#413-lazycalls).\n\n##### 2.2.1 abstract class\n\nexample with ES6 class syntax\n```javascript\ndi.addRule('B',{\n  classDef: B,\n})\n\n@di('A',[ 'B' ])\nclass A{\n  constructor(b){\n    this.b = b\n  }\n}\n\ndi.get('A')\n```\n\nexample with function as constructor or factory\n```javascript\ndi.addRule('B',{\n  classDef: B,\n})\n\nfunction A(b){\n  this.b = b\n}\ndi( 'A', ['B'] )( A )\n\ndi.get('A')\n```\n\n##### 2.2.2 reference class\n```javascript\n@di('A',[ B ])\nclass A{\n  constructor(b){\n    this.b = b\n  }\n}\n\ndi.get('A')\n```\n\n### 3. Dependencies Resolution\nThe dependencies are resolved according to rule's key [`params`](#411-params) and parameters of call argument for rule's key [`calls`](#412-calls) and [`lazyCalls`](#413-lazycalls).\n\n#### 3.1 Recursive classes or factories\nYou can use factories or classes, and obviously, all dependencies are resolved recursively.\n```javascript\nclass A{\n  constructor(b){\n    this.b = b\n  }\n}\nclass B{\n  constructor(c){\n    this.c = c\n  }\n}\nfunction C(){\n  return 'Hello world !'\n}\ndi.addRules({\n  A: {\n    classDef: A,\n    params: [ 'B' ],\n  },\n  B: {\n    classDef: B,\n    params: [ 'C' ],\n  },\n  C: {\n    classDef: C,\n  },\n})\n\nconst a = di.get('A') //will resolve C and pass it's return to new B, then it will pass the new B to new A\n\n//it will be equivalent to\nconst a = new A( new B( C() ) )\n```\n\n#### 3.2 Recursive params\nYou can nest dependencies declarations to infinite. It's very common use for config.  \n(for others params behaviors see [`params`](#411-params))\n\n```javascript\nclass A{\n  constructor(config, aSecondInstanceOfB){\n    this.b = config.wathever.anotherKey.b\n    this.b2 = aSecondInstanceOfB\n  }\n}\nclass B{}\ndi.addRules({\n  A: {\n    classDef: A,\n    params: [ {\n      wathever: {\n        anotherKey: {\n          b: 'B'\n        },\n      },\n    }, 'B' ],\n  },\n  B: {\n    classDef: B,\n  },\n})\n\nconst a = di.get('A')\n\n//it will be equivalent to\nconst a = new A( {\n  wathever: {\n    anotherKey: {\n      b: new B(),\n    },\n  },\n}, new B() )\n```\n\n#### 3.3. Types of params\nYou can wrap each value of param with a di-ninja class that will tell container how to resolve the dependency.  \nBy default all values and subvalues of params are traversed when it's an Object or Array,\nare wrapped with `classFactory` when it's a function, and else by `interface`.  \nAll these behaviors can be configured, but the default config is well and the documentation rely on it.\n(see\n[`defaultVar`](#57-defaultvar),\n[`defaultRuleVar`](#58-defaultrulevar),\n[`defaultDecoratorVar`](#59-defaultdecoratorvar),\n[`defaultArgsVar`](#510-defaultargsvar),  \n[`defaultFactory`](#511-defaultfactory),\n[`defaultFunctionWrapper`](#512-defaultfunctionwrapper))\n\n(for others params behaviors see [`params`](#411-params))\n\n##### 3.3.1 interface\nContainer will resolve dependency as, an instance of class or a value from factory, defined by corresponding rule's key.  \nThis is the default wrapper for string.\n```javascript\nclass A{\n  constructor(b){\n    this.b = b\n  }\n}\nclass B{}\n\ndi.addRule('A', { classDef: A })\ndi.addRule('B', { classDef: B })\n\ndi.addRule('A', { params: [ di.interface('B') ] })\n\n//with default config, previous rule will be equivalent to next one\ndi.addRule('A', { params: [ 'B' ] })\n\n\nconst a = di.get('A')\n\n//will be equivalent to\nconst a = new A( new B() )\n```\n\n##### 3.3.2 value\nContainer will resolve dependency with the specified value. The value type can be anything: scalar, object, array, function...\n```javascript\nclass A{\n  constructor(bar){\n    this.foo = bar\n  }\n}\n\ndi.addRule('A', {\n  classDef: A,\n  params: [ di.value('bar') ],\n})\n\nconst a = di.get('A')\n\n//will be equivalent to\nconst a = new A( 'bar' )\n```\n\n##### 3.3.3 factory\nThe behavior of this method can be configured with container config's key [`defaultFactory`](#511-defaultfactory).  \nBy default it's an alias for [`valueFactory`](#334-valuefactory).\n\n##### 3.3.4 valueFactory\nContainer will resolve dependency with the value returned by the given function.\n```javascript\nclass A{\n  constructor(bar){\n    this.foo = bar\n  }\n}\n\nfunction getFoo(){\n  return 'bar'\n}\n\ndi.addRule('A', {\n  classDef: A,\n  params: [ di.factory( getFoo ) ],\n})\n\nconst a = di.get('A')\n\n//will be equivalent to\nconst a = new A( getFoo() )\n```\n\n##### 3.3.5 classFactory\nContainer will resolve dependency with an instance of the referenced class (or the returned value of a factory).  \nThis is the default wrapper for classes references.\n```javascript\nclass A{\n  constructor(b){\n    this.b = b\n  }\n}\nclass B{}\n\ndi.addRule('A', { classDef: A })\n\ndi.addRule('A', { params: [ di.classFactory(B) ] })\n\n//with default config, previous rule will be equivalent to next one\ndi.addRule('A', { params: [ B ] })\n\n\nconst a = di.get('A')\n\n//will be equivalent to\nconst a = new A( new B() )\n```\n\n##### 3.3.4 require\nContainer will resolve dependency with an instance (or value returned by the function)\nof the class (or factory) (CJS export or ES6 export default) exported by specified file.  \nYou can use rules to configure it.  \nThe behavior of this method differ according to environment:  \nin all environment it will rely on preloaded require.context (see [`dependencies`](#53-dependencies))\nwich is the only way to include dependency in webpack (because of static require resolution),\nfor node, if the dependency it's not registred, it will require the specified file and register it.\n```javascript\ndi.addRules({\n  'A': {\n    classDef: A,\n    params: [ di.require('path/to/my-file') ],\n  },\n  'path/to/my-file': {\n    /* ... */\n  },\n)\n\nconst a = di.get('A')\n```\n\n\n### 4. Rules\nThe rules define resolutions behaviors of the classes or factories and their dependencies.\n```javascript\nconst rules = {}\n\n//1st way to define rules\nconst di = container()\ndi.addRules(rules)\n\n//2nd way to define rules\nconst di = container({\n  rules,\n})\n```\n\n#### 4.1. dependencies\nThe following rule's keys are about classes or factories dependencies.\n```javascript\n//you can use class\nclass A{\n  constructor(b, c, d){\n    this.b = b\n    this.c = c\n    this.d = d\n  }\n}\n\n//or instance factory\nfunction A(b, c, d){\n  this.b = b\n  this.c = c\n  this.d = d\n}\n\n//or factory\nfunction A(b, c, d){\n  const anotherValue = {\n    b: b,\n    c: c,\n    d: d,\n  }\n  return anotherValue\n}\n```\n\n##### 4.1.1 params\ntype: **array**  \ncontaining nested dependencies\n\nThe rule's key `params` define what will be injected to class constructor or factory.\nThe keys can be nested (see [Recursive params](#32-recursive-params)).\nThe resolutions behavior depends of [Types of params](#33-types-of-params).\n\n```javascript\nclass A{\n  constructor(b, c, d){\n    this.b = b\n    this.c = c\n    this.d = d\n  }\n}\n\ndi.addRule('A', { params: ['B','C','D'] })\n\n```\n\nYou can override params defined in rule on manual call:\n```javascript\ndi.get('A', ['E','F','G'])\n\n```\n\n##### 4.1.2 calls\ntype: **array**  \nstack of call array with 1st item for method name or callback and 2nd item an array of params for methods (working same as [`params`](#411-params)).\n\nStack of methods to call after instance creation.  \nIf some circular dependencies are detected, some items of calls stack will be placed automatically in [`lazyCalls`](#413-lazycalls).\n\n```javascript\nclass A{\n  method1(dep1){\n    this.dep1 = dep1\n  }\n  method2(dep2){\n    this.dep2 = dep2\n  }\n  method3(dep3){\n    this.dep3 = dep3\n  }\n}\ndi.addRule('A', {\n  classDef: A,\n  calls: [\n    \n    [ 'method1', [ 'dep1' ] ],\n    [ 'method2', [ 'dep2' ] ],\n    \n    [\n      function(a, dep3){\n        a.method3(dep3)\n      },\n      [ 'dep3' ]\n    ],\n    \n  ],\n})\n\n```\n\n##### 4.1.3 lazyCalls\ntype: **array** \n\nSame as [`calls`](#412-calls), but run after dependency has been distributed to needing instances, this helper offer a simple way to solving circular dependency problem.\n\n#### 4.2. instantiation\nThe following rule's keys are about instantiations of classes and factories.\n\n##### 4.2.1 classDef\ntype: **function**\nclass or factory\n\nThe `classDef` key reference the class that will be used for instantiation.  \nIt's used for use reference to class direcly in rule, you can do without if you configure container [`dependencies`](#53-dependencies) with require.context.\n```javascript\nclass A{}\n\ndi.addRule('A',{ classDef: A ])\n\nassert( di.get('A') instanceof A )\n```\n\n##### 4.2.2 instanceOf\ntype: **string**\ninterface name\n\nRefers to the name of another rule containing [`classDef`](#421-classdef) or `instanceOf`, this is resolved recursively.\n```javascript\ndi.addRule('A',{ classDef: A })\ndi.addRule('B',{ instanceOf: 'A' })\n\nassert( di.get('B') instanceof A )\n```\n\n##### 4.2.3 substitutions\ntype: **object** | **array**\n\nSubstitutions, as indicated by it's name,\nsubstitutes a dependency defined by [`params`](#411-params), [`calls`](#412-calls) (and [`lazyCalls`](#413-lazycalls)).\nIf an object is provided, the substitutions operate by associative key, else, if an array is provided, the substitution will be done only for `params` and will be index based.  \nBy associative key, all dependencies of the rule's named as the key will be replaced by specified other rule's name.\n\nindex based\n```javascript\n@di('A', [ 'B' ])\nclass A{\n  constructor(B){\n    this.B = B\n  }\n}\n\ndi.addRule('A',{\n  substitutions: [ 'C' ],\n})\n\nassert( di.get('A').B instanceof C )\n```\n\nassociative key\n```javascript\n@di('A', [ { config: { subkey: 'B' } } ])\nclass A{\n  constructor(config){\n    this.B = config.subkey.B\n  }\n}\ndi.addRule('A',{\n  substitutions: { 'B': 'C' },\n})\n\nassert( di.get('A').B instanceof C )\n```\n\nassociative key for calls\n```javascript\nclass A{\n  setDep(config){\n    this.dep = config.dep\n  }\n}\ndi.addRule('A',{\n  calls: [\n    [ 'setDep', [ { dep: 'B' } ] ],\n  ],\n  substitutions: { 'B': 'C' },\n})\n\nassert( di.get('A').dep instanceof C )\n```\n\n\n#### 4.3. single instance\nThe following rule's keys are about sharing single instances.\n\n##### 4.3.1 shared\ntype: **boolean** (default false)\n\nWhen `shared` is set to `true`, the instance of the classe or the factory return defined by the rule will be shared for the whole application.\n```javascript\nclass A{\n  constructor(b){\n    this.b = b\n  }\n}\nclass B{}\n\ndi.addRules({\n  'A': {\n    params: [ 'B' ],\n  },\n  'B': {\n    shared: true,\n  },\n})\n\nconst a1 = di.get('A')\nconst a2 = di.get('A')\nassert( a1 !== a2 )\n\nassert( a1.b === a2.b )\n\nconst b1 = di.get('B')\nconst b2 = di.get('B')\nassert( b1 === b2 )\n\n```\n\n##### 4.3.2 singleton\ntype: **object** | **array** | **scalar**\n\nIf specified it will be registred as shared instance of the dependency for the whole application.\n```javascript\nclass A{\n  constructor(b){\n    this.b = b\n  }\n}\nclass B{}\n\nconst b = new B()\n\ndi.addRules({\n  'A': {\n    params: [ 'B' ],\n  },\n  'B': {\n    singleton: b,\n  },\n})\n\nconst a1 = di.get('A')\nconst a2 = di.get('A')\nassert( a1 !== a2 )\n\nassert( a1.b === a2.b === b )\n\nconst b1 = di.get('B')\nconst b2 = di.get('B')\nassert( b1 === b2 === b )\n\n```\n\n##### 4.3.3 sharedInTree\nIn some cases, you may want to share a a single instance of a class between every class in one tree but if another instance of the top level class is created, have a second instance of the tree.\n\nFor instance, imagine a MVC triad where the model needs to be shared between the controller and view, but if another instance of the controller and view are created, they need a new instance of their model shared between them.\n\nThe best way to explain this is a practical demonstration:\n```javascript\nclass A {    \n  constructor(b, c){\n    this.b = b\n    this.c = c\n  }\n}\n\nclass B {\n  constructor(d){\n    this.d = d\n  }\n}\n\nclass C {\n  constructor(d){\n    this.d = d\n  }\n}\n\nclass D {}\n\ndi.addRule('A', {\n  'sharedInTree': ['D'],\n})\n\nconst a = di.get('A')\n\n// Anywhere that asks for an instance D within the tree that existis within A will be given the same instance:\n// Both the B and C objects within the tree will share an instance of D\nassert( a.b.d === a.c.d )\n\n// However, create another instance of A and everything in this tree will get its own instance of D:\nconst a2 = di.get('A')\nassert( a2.b.d === a2.c.d )\n\nassert( a.b.d !== a2.b.d )\nassert( a.c.d !== a2.c.d )\n\n```\n\nBy using `sharedInTree` it's possible to mark D as shared within each instance of an object tree.\nThe important distinction between this and global shared objects is that this object is only shared within a single instance of the object tree. \n\n\n#### 4.4. rule inheritance\nThe following rule's keys are about rule inheritance.  \nThere are three way to herit rule, the priority order of override is\n[`inheritInstanceOf`](#441-inheritinstanceof),\noverrided by [`inheritPrototype`](#442-inheritprototype), \noverrided by [`inheritMixins`](#443-inheritmixins), \nand finally the rule itself wich is composed by rule definition and [`decorator`](#444-decorator).\nPriority between rule and decorator depends of calls order, the last take precedence, traditionally it's the rule.  \nMost of rules options are replaced except some options that will be merged:\n[`sharedInTree`](#433-sharedintree), [`substitutions`](#423-substitutions),\n[`calls`](#412-calls) and [`lazyCalls`](#413-lazycalls).\n\nSee also [`rulesDefault`](#52-rulesDefault) in container config section.\n\n##### 4.4.1 inheritInstanceOf\ntype: **boolean** (default true)  \nEnable inheritance of rules from instanceOf parents classes.\n\n```javascript\nclass X{\n  constructor(x){\n    this.x = x\n  }\n}\n    \ndi.addRules({\n  'X':{\n    classDef: X,\n    params: [ di.value('ok') ],\n    shared: true,\n  },\n  'Y':{\n    instanceOf: 'X',\n    inheritInstanceOf: true,\n  },\n})\n\nassert( di.get('Y').x === 'ok' )\nassert( di.get('Y') === di.get('Y') )\n\n```\n\n##### 4.4.2 inheritPrototype\ntype: **boolean** (default false)  \n\nEnable inheritance of rules from ES6 extended parents classes.  \n[`decorator`](#444-decorator) must be enabled to parents rules you want to extend from.\n```javascript\nclass Z{\n  constructor(...params){\n    this.params = params\n  }\n}\nclass ZX extends Z{}\n\ndi.addRules({\n  'Z': {\n    classDef: Z,\n    params: [ di.value(1), di.value(2), di.value(3) ],\n    decorator: true, //needed for parent class by extended using inheritPrototype\n  },\n  'Z2': {\n    classDef: ZX,\n    inheritPrototype: true,\n  },\n})\n\nconst z   = di.get('Z').getParams()\nconst z2  = di.get('Z2').getParams()\nassert.deepEqual(z2, z)\n\n```\n\n##### 4.4.3 inheritMixins\ntype: **array**\n\nEnable inheritance from a list of specified rules.\n```javascript\nclass A{\n  constructor(...params){\n    this.params = params\n  }\n  getParams(){\n    return this.params\n  }\n}\nclass B{\n  constructor(...params){\n    this.params = params\n  }\n  getParams(){\n    return this.params\n  }\n}\n\ndi.addRules({\n  'A':{\n    classDef: A,\n    params: [ di.value('a') ],\n  },\n  'B':{\n    classDef: B,\n    inheritMixins: [ 'A' ],\n  },\n})\n\nconst a = di.get('A').getParams()\nconst b = di.get('B').getParams()\nassert.deepEqual(b, a)  \n```\n\n##### 4.4.4 decorator\ntype: **boolean** (default false)\n\nWhen set to `true`, a [`Symbol`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) property\nwill be set on class or factory function, allowing to use [`inheritPrototype`](#442-inheritprototype).\nIf the [decorator injection approach](#22-decorator-injection-approach) is used, it's not necessary to configure this rule,\nbecause the Symbol will be set whatever the decorator key value is.  \nThis is required to enable [`inheritPrototype`](#442-inheritprototype) feature.\n\n#### 4.5. asynchronous dependencies resolution\nThe following rule's keys allow you to manage the asynchronous dependencies resolution flow.  \nWhen a dependency return a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\nand this promise is waited for resolution by [`asyncResolve`](#541-asyncresolve),\nthe outputed object of `di.get()` method will be a Promise object,\nwich will be resolved by the expected object.\n\n##### 4.5.1 asyncResolve\ntype: **boolean** (default false)\n\nWhen set to `true`, if a factory return a Promise, the dependency tree will wait for it's resolution,\nand then call the requiring dependency with the Promise's resolved value.  \nPromise is detected with instanceof operator, if you want to use a specific Promise polyfill (eg: [bluebird](http://bluebirdjs.com)) you can use\nthe [`promiseFactory`](#513-promisefactory) and [`promiseInterfaces`](#514-promiseinterfaces) container's config options.\n\n```javascript\nfunction A(b, c){\n  this.b = b\n  this.c = c\n}\nasync function B(){\n  return 'b'\n}\nasync function C(){\n  return 'c'\n}\n\ndi.addRules({\n  'A': {\n    classDef: A,\n    params: ['B','C'],\n  },\n  'B': {\n    classDef: B,\n    asyncResolve: true,\n  },\n  'C': {\n    classDef: C,\n    asyncResolve: false, //default\n  },\n})\n\ndi.get('A').then(a =\u003e {\n  assert(a.b === 'b')\n  assert(a.c instanceof Promise)\n})\n\n```\n\n##### 4.5.2 asyncCallsSerie\ntype: **boolean** (default false)\n\nWhen set to `true`, defer [`calls`](#412-calls) resolution sequentially\nwhen the method or callback require a dependency returning a Promise and for wich [`asyncResolve`](#451-asyncresolve) rule option setted to true.\n\n```javascript\nclass A{\n  setB(d){\n    this.b = ++d.i\n  }\n  setC(d){\n    this.c = ++d.i\n  }\n}\n\nfunction B(d){\n  return new Promise((resolve)=\u003e{\n    setTimeout(()=\u003e{\n      resolve(d)\n    }, 200)\n  })\n}\nfunction C(d){\n  return new Promise((resolve)=\u003e{\n    setTimeout(()=\u003e{\n      resolve(d)\n    }, 100)\n  })\n}\n\nfunction D(){\n  this.i = 0\n}\n\ndi.addRules({\n  'A': {\n    classDef: A,\n    calls: [\n      ['setB', ['B'] ],\n      ['setC', ['C'] ],\n    ],\n    sharedInTree: ['D'],\n    asyncCallsSerie: false, //default\n  },\n  'A2': {\n    instanceOf: 'A',\n    asyncCallsSerie: true,\n  },\n  \n  'B': {\n    classDef: B,\n    params: ['D'],\n    asyncResolve: true,\n  },\n  'C': {\n    classDef: C,\n    params: ['D'],\n    asyncResolve: true,\n  },\n  'D':{\n    classDef: D,\n  },\n  \n  \n})\n\ndi.get('A').then( a =\u003e {\n  assert.strictEqual(a.b, 2)\n  assert.strictEqual(a.c, 1)\n} )\n\ndi.get('A2').then( a =\u003e {\n  assert.strictEqual(a.b, 1)\n  assert.strictEqual(a.c, 2)\n} )\n```\n\n##### 4.5.3 asyncCallsParamsSerie\ntype: **boolean** (default false)\n\nWhen set to `true`, ensure that the dependencies stacks for all [`calls`](#412-calls) of a dependency are resolved sequentially according to order of calls,\nwhen the method or callback require a dependency returning a Promise and for wich [`asyncResolve`](#451-asyncresolve) rule option setted to true.\nSetted to true, it will implicitly set [`asyncCallsSerie`](#452-asynccallsserie) to true.\n\n```javascript\nclass A{\n  setB(b){\n    this.b = b\n  }\n  setC(c){\n    this.c = c\n  }\n}\n\nfunction B(d){\n  return new Promise((resolve)=\u003e{\n    setTimeout(()=\u003e{\n      resolve(++d.i)\n    }, 200)\n  })\n}\nfunction C(d){\n  return new Promise((resolve)=\u003e{\n    setTimeout(()=\u003e{\n      resolve(++d.i)\n    }, 100)\n  })\n}\n\nfunction D(){\n  this.i = 0\n}\n\ndi.addRules({\n  'A': {\n    classDef: A,\n    calls: [\n      ['setB', ['B'] ],\n      ['setC', ['C'] ],\n    ],\n    asyncCallsParamsSerie: true,\n    sharedInTree: ['D'],\n  },\n  'B': {\n    classDef: B,\n    params: ['D'],\n    asyncResolve: true,\n  },\n  'C': {\n    classDef: C,\n    params: ['D'],\n    asyncResolve: true,\n  },\n  'D':{\n    classDef: D,\n  },\n})\n\ndi.get('A').then( a =\u003e {\n  assert(a.b === 1)\n  assert(a.c === 2)\n})\n\n```\n\n#### 4.6 dependency file location\nThe following rule's keys are about dependency file location.  \n\n##### 4.6.1 autoload\ntype: **boolean** (default false)\n\nWhen set to `true`, check for allready registred dependency and if not, in node, try to require it,\nif dependency is not found it can (maybe) throw an Error according to [`autoloadFailOnMissingFile`](#56-autoloadfailonmissingfile) container config.  \nThe require path resolution is based first on [`path`](#462-path) rule option if defined,\nthen on [`instanceOf`](#422-instanceof) rule option if defined (if instanceOf point to a rule with it's own path it will get it),\nand finally on the key of the rule.\nThis require path can be post-processed using [`autoloadPathResolver`](#54-autoloadpathresolver) container config.  \nThe colons character `:` can be used to get a subkey of exported,\nand you can use it multiple times in same expression to get nested value.\nWhen [`path`](#462-path) is defined it will implicitly set autoload to true.\n\n```javascript\ndi.addRules({\n  'http:Server':{\n    autoload: true,\n  },\n  '#server': {\n    instanceOf: 'http:Server',\n    autoload: true,\n  },\n  '#server2': {\n    path: 'http:Server',\n  },\n  \n})\n\nassert( di.get('http:Server') instanceof require('http').Server )\nassert( di.get('#server') instanceof require('http').Server )\nassert( di.get('#server2') instanceof require('http').Server )\n```\n\n##### 4.6.2 path\ntype: **string**  \n\nThe require path can be post-processed by [`autoloadPathResolver`](#54-autoloadpathresolver) container config.  \nWhen defined it will implicitly set [`autoload`](#461-autoload) to true.  \nYou can traverse exported and get specific key using colons character `:`.  \nYou can't use relative path, if you want to include relative path, your application source files for exemple,\nyou have to alias directories (or files) using [`autoloadPathResolver`](#54-autoloadpathresolver) feature.  \nSee [`autoload`](#461-autoload) section for more details on the requiring behavior based on implicit path with instanceOf and rule's key.\n\n```javascript\ndi.addRules({\n  '#server': {\n    path: 'http:Server',\n  },\n})\n\nassert( di.get('#server') instanceof require('http').Server )\n```\n\n\n### 5. Container\nThe container config options manage the container behavior and the way that the rules are resolving.\n```javascript\nimport container from 'di-ninja'\n\n//set config on container creation\nconst di = container(config)\n\n//or using config method\nconst di = container()\ndi.config(config)\ndi.config('aConfigKey', aConfigValue)\n```\nOrder of config calls doesn't matter except for options [`dependencies`](#53-dependencies) and [`rules`](#51-rules) wich must be called at end.\nIf key/value config object is provided as config param, options will be treated in the correct order.\n\n#### 5.1 rules\nSee [`rules`](#4-rules) section.\n```javascript\ndi.config({\n  rules\n})\n\n//or\ndi.config('rules',rules)\n\n//or\ndi.addRules(rules)\ndi.addRule('#myClassName', rule)\n```\n\n#### 5.2 rulesDefault\nDefault values for rules, each rule will be extended from this setup, values will be overidded or merged.  \nSee [rule inheritance](#44-rule-inheritance) documentation section for more details on extending.\nSee [`rules`](#4-rules) section for rules options.\n```javascript\ndi.config('rulesDefault',rulesDefault)\n```\n\n#### 5.3 dependencies\nDependencies is intendeed to allow you to \"inject\" require's context directories as preload dependencies.\nIt work using the webpack `require.context` feature,\nbut a node polyfill called `container.context` is provided with di-ninja allowing you to build isomorphic architecture.  \nsee also [`polyfillRequireContext`](#519-polyfillrequirecontext)\n\nNodeJS example\n```javascript\nimport container from 'di-ninja'\n\nconst di = container({\n  rules:{\n    'app/A': {\n      \n    },\n    'app/B': {\n      \n    },\n    'app/B/C': {\n      \n    },\n  },\n  \n  dependencies: {\n    \n    'app' : container.context('./src', true, /\\.js$/),\n    \n    'A': container.require('./src/A'),\n    \n    'B': container.dependency(require('./src/B')),\n    \n  },\n})\n\nassert( di.get('app/A') instanceof require('./src/A').default )\n\nassert( di.get('app/B') instanceof require('./src/B').default )\n\nassert( di.get('app/B/C') instanceof require('./src/B/C').default )\n\nassert( di.get('A') instanceof require('./src/A').default )\n\nassert( di.get('B') instanceof require('./src/B').default )\n\n```\n\n\nIsomorphic example  \nUse the same code for browser compilation (via webpack for example) than on server-side with nodejs.  \n\nin webpack.config.js\n\n```javascript\nconst webpack = require('webpack')\n\nmodule.exports = {\n  plugins: [\n    new webpack.DefinePlugin({\n      'process.env': {\n        APP_ENV: JSON.stringify('browser')\n      }\n    }),\n  ],\n  /* ... */\n}\n\n```\n\nand in your dependency-injection config file\n```javascript\nimport container from 'di-ninja'\n\nif(process.env.APP_ENV !== 'browser'){\n  //we are not in webpack/browser but in nodejs/server-side\n  require.context = container.context\n}\n\nconst di = container({\n  rules:{\n    'app/A': {\n      \n    },\n    'app/B': {\n      \n    },\n    'app/B/C': {\n      \n    },\n    \n  },\n  \n  dependencies: {\n    'app' : require.context('./src', true, /\\.js$/),    \n    \n    'A': container.dependency( require('./src/A') ),\n    \n    'B': container.dependency( require('./src/B') ),\n  },\n})\n\nassert( di.get('app/A') instanceof require('./src/A').default )\n\nassert( di.get('app/B') instanceof require('./src/B').default )\n\nassert( di.get('app/B/C') instanceof require('./src/B/C').default )\n\nassert( di.get('A') instanceof require('./src/A').default )\n\nassert( di.get('B') instanceof require('./src/B').default )\n```\n\n\n#### 5.4 autoloadPathResolver\nRule's path post-processor callback function or alias map object.\n\nwith callback\n```javascript\ndi.config('autoloadPathResolver', (path)=\u003e{\n  switch(path){\n    case 'framework':\n      path = 'express'\n    break\n  }\n  return path\n})\n```\n\nwith alias map object\n```javascript\nimport path from 'path'\nconst aliasMap = {\n  'app': path.resolve(__dirname, './src'),\n}\n\ndi.config('autoloadPathResolver', aliasMap)\n\n\n//will implicitly set the following predefined callback, here is the magic under the hood\ndi.config('autoloadPathResolver', (path)=\u003e{\n  Object.keys(aliasMap).forEach(alias=\u003e{\n    const realPath = aliasMap[alias]\n    if(path == alias){\n      path = realPath\n    }\n    else if(path.substr(0,alias.length+1)==alias+'/'){\n      path = realPath+path.substr(alias.length)\n    }\n  })\n  return path\n})\n```\n\n#### 5.5 autoloadExtensions\nYou can use Array or RegExp.\n```javascript\ndi.config('autoloadExtensions', ['js', 'jsx'])\n\ndi.config('autoloadExtensions', new RegExp('\\.(js|jsx)$'))\n```\n\n\n#### 5.6 autoloadFailOnMissingFile\nPossible values are string `path`, `true` or `false`.  \nSetted to false, it will never throw error on missing dependency.  \nSetted to true, it will always throw an error on missing dependency.  \nSetted to `path`, it will throw error only if a dependency with a specified rule's option [`path`](#462-path) is specified.\nThe default value is `path`.  \n\n```javascript\ndi.config('autoloadFailOnMissingFile', true)\n```\n\n#### 5.7 defaultVar\nValue by default for\n[`defaultRuleVar`](#58-defaultrulevar),\n[`defaultDecoratorVar`](#59-defaultdecoratorvar),\nand [`defaultArgsVar`](#510-defaultargsvar).\n\nThis is about implicit wrapping of [`params`](#411-params), [`calls`](#412-calls) and [`lazyCalls`](#413-lazycalls).\n\nPossible values are `interface` or `value`.  \nDefault is `interface`.  \n\n`interface` mean that all scalar values will be implicitly wrapped by di.interface(), it will be resolved as class.\n`value` mean that all scalar values will be wrapped by di.value(), it will be left as untouched.\n\ninterface example\n```javascript\ndi.config('defaultVar', 'interface') //default\n\ndi.addRule('A', {\n  params: [\n    {\n      B :        'B',\n      message :  di.value( 'Hello world !' ),\n      config :  di.value({\n        option1: value1\n        /* ... */\n      }),\n    }\n  ]\n})\n```\n\n\nvalue example\n```javascript\ndi.config('defaultVar', 'value')\n\ndi.addRule('A', {\n  params: [\n    {\n      B :        di.interface('B'),\n      message :  'Hello world !',\n      config :  di.value({\n        option1: value1\n        /* ... */\n      }),\n    }\n  ]\n})\n```\n\n#### 5.8 defaultRuleVar\nImplicit wrapping for scalar values defined from [`rules`](#4-rules).  \nsee [`defaultVar`](#57-defaultvar).\n\n\n#### 5.9 defaultDecoratorVar\nImplicit wrapping for scalar values defined from [`decorator`](#444-decorator).  \nsee [`defaultVar`](#57-defaultvar).\n\n\n#### 5.10 defaultArgsVar\nImplicit wrapping for scalar values defined from manual call (see [`params`](#411-params)).  \nsee [`defaultVar`](#57-defaultvar).\n\n#### 5.11 defaultFactory\ndefault wrapper class to instanciate for di.factory() method.\n\n#### 5.12 defaultFunctionWrapper\nImplicit wrapping for function or class values.  \nPossible values are ClassFactory or ValueFactory.  \nThe default value is ClassFactory.\n\nClassFactory example\n```javascript\nimport ClassFactory from 'di-ninja/dist/classFactory'\ndi.config('defaultFunctionWrapper', ClassFactory) //default\n\nclass B{}\n\ndi.addRule('A', {\n  params: [\n    B,\n    di.valueFactory( () =\u003e {\n      return 'Hello world !'\n    } )\n  ],\n})\n```\n\nValueFactory example\n```javascript\nimport ValueFactory from 'di-ninja/dist/valueFactory'\ndi.config('defaultFunctionWrapper', ValueFactory)\n\nclass B{}\n\ndi.addRule('A', {\n  params: [\n    di.classFactory( B ),\n    () =\u003e {\n      return 'Hello world !'\n    }\n  ],\n})\n```\n\n#### 5.13 promiseFactory\ndefault: Promise (global)  \n`promiseFactory` option let you modify the way DiNinja create Promise for handle [`asyncResolve`](#451-asyncresolve).  \nFor example, you can use it with bluebird.  \nThe common way is to use it in combination with [`promiseInterfaces`](#514-promiseinterfaces) option.\n\n```javascript\nimport bluebird from 'bluebird'\n\ndi.config('promiseFactory', bluebird)\n\nfunction A (b) {\n  this.b = b\n}\nfunction B () {\n  return new Promise((resolve, reject) =\u003e {\n  resolve('b')\n  })\n}\n\ndi.addRules({\n  'A': {\n  classDef: A,\n  params: ['B']\n  },\n  'B': {\n  classDef: B,\n  asyncResolve: true\n  }\n})\n\nassert( di.get('A') instanceof bluebird )\n\n```\n\n#### 5.14 promiseInterfaces\ndefault: Promise (global)  \n`promiseInterfaces` option let you modify the way DiNinja recognize Promise.  \nFor example, you can use it with bluebird.  \nThe common way is to use it in combination with [`promiseFactory`](#513-promisefactory) option.  \nThe [`promiseFactory`](#513-promisefactory) option will automatically be pushed to promiseInterfaces.\n\n```javascript\nimport bluebird from 'bluebird'\n\ndi.config('promiseInterfaces', [ bluebird, Promise /* let the standard Promise be identified */ ])\n\nfunction A(b){\n  this.b = b\n}\nfunction B(){\n  return new bluebird((resolve, reject)=\u003e{\n    resolve('b')\n  })\n}\n\ndi.addRules({\n  'A': {\n    classDef: A,\n    params: ['B'],\n  },\n  'B': {\n    classDef: B,\n    asyncResolve: true,\n  },\n})\n\nassert( di.get('A') instanceof Promise )\n\n```\n\n#### 5.15 interfacePrototype\nEnable you to use [`Symbol`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) based\ninterface reference instead of string as dependency key, allowing you to use runtime [`interfaceTypeCheck`](#516-interfacetypecheck).\n```javascript\nimport {\n  InterfacePrototype,\n  instanceOf,\n  Interface,\n} from 'interface-prototype'\n\ndi.config('interfacePrototype', InterfacePrototype)\n    \nconst I = new Interface();\n\n@di('A')\n@instanceOf(I)\nclass A{}\n\n@di('B')\n@instanceOf(I)\nclass B{}\n\ndi.addRules({\n  [I]: {\n    classDef: A,\n  }\n})\n\n@di('D', [I])\nclass D {\n  constructor(i){\n    this.i = i;\n  }\n}\n\nassert(di.get('A') instanceof I)\nassert(di.get('B') instanceof I)\n\nassert(di.get(I) instanceof A)\nassert( !( di.get(I) instanceof B ))\n\nassert(di.get('D').i instanceof A)\n \n```\n\n#### 5.16 interfaceTypeCheck\ntype: **boolean** (default false)\n\nEnable check for \"implemented\" interface using [`interfacePrototype`](#515-interfaceprototype).\nIf a manually provided dependency doesn't \"implement\" the required \"interface\", it will throw an error.  \nIn combination with [interface-prototype](https://github.com/di-ninja/interface-prototype),\nthis enable runtime type-check and custom type-check for all type of variables.  \n\n\n#### 5.17 globalKey\ntype: **string** | **boolean** (default false)  \nWhen setted to true it will be transformed to string 'di'.  \nIf provided, global.globalKey (on node) or window.globalKey (on browser) will be set to the instance of container.\n```javascript\ncontainer({\n  globalKey: 'di',\n})\n\ndi.get('A')\n```\n\n#### 5.18 ruleCache\ntype: **boolean** (default true)  \nEnable cache for built rules, optimizing the future calls of `di.get()`.  \nYou can set it to false when you have rules dynamically modified after some `di.get()` calls.\n```javascript\ndi.config('ruleCache', false)\n\ndi.addRule('A', { params: [ 'B' ] })\n\nconst a1 = di.get('A')\n\ndi.addRule('A', { params: [ 'C' ] })\n\nconst a2 = di.get('A')\n```\n\n#### 5.19 polyfillRequireContext\ntype: **boolean** (default false)  \nThis is an experimental feature, so be carefull.  \nIt will automatically polyfill the [webpack's `require.context` method](https://webpack.js.org/guides/dependency-management/#require-context) to nodejs environment.  \nIt's an helper to enforce easy isomorphism (cross-environment).  \nSee also [`dependencies`](#53-dependencies) for the hack-less technic\n\n### 6 Examples\n\nHere is a list of examples of complex di-ninja implementations with dependencies wired by directories:\n1. [di-ninja-nodejs-example](https://github.com/di-ninja/di-ninja-nodejs-example) (using di-ninja node polyfill for `require.context()`)\n2. [di-ninja-webpack-example](https://github.com/di-ninja/di-ninja-webpack-example) (using `require.context()` native method of webpack)\n3. [di-ninja-reactnative-example](https://github.com/di-ninja/di-ninja-reactnative-example) (using [babel-plugin-require-context-polyfill](https://github.com/di-ninja/babel-plugin-require-context-polyfill))\n\n\n## About\nBuilt with [babel](https://babeljs.io/).   \nWork with NodeJS, [Webpack](https://webpack.js.org/), React-Native and UMD/AMD (requirejs).\nInspired by [strategy](https://github.com/redcatphp/strategy) for php, itself based on [dice](https://r.je/dice.html) design.\nMade with ❤️ and 🦊.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdi-ninja%2Fdi-ninja","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdi-ninja%2Fdi-ninja","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdi-ninja%2Fdi-ninja/lists"}