{"id":21872415,"url":"https://github.com/zerkalica/reactive-di","last_synced_at":"2025-08-29T13:06:09.326Z","repository":{"id":57348186,"uuid":"48166545","full_name":"zerkalica/reactive-di","owner":"zerkalica","description":"Extensible hierarchical dependency injection container with flowtype interface support","archived":false,"fork":false,"pushed_at":"2018-03-27T16:11:17.000Z","size":1500,"stargazers_count":39,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-15T00:07:49.059Z","etag":null,"topics":["atom","context","dependency-injection","lom-atom","mobx","mobx-react","react","reactive-programming","state-management"],"latest_commit_sha":null,"homepage":"","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/zerkalica.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-17T09:57:32.000Z","updated_at":"2025-03-29T20:07:51.000Z","dependencies_parsed_at":"2022-08-31T16:44:45.447Z","dependency_job_id":null,"html_url":"https://github.com/zerkalica/reactive-di","commit_stats":null,"previous_names":[],"tags_count":141,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerkalica%2Freactive-di","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerkalica%2Freactive-di/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerkalica%2Freactive-di/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerkalica%2Freactive-di/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zerkalica","download_url":"https://codeload.github.com/zerkalica/reactive-di/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248981267,"owners_count":21193147,"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":["atom","context","dependency-injection","lom-atom","mobx","mobx-react","react","reactive-programming","state-management"],"created_at":"2024-11-28T06:20:41.647Z","updated_at":"2025-04-15T00:07:58.089Z","avatar_url":"https://github.com/zerkalica.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Reactive DI  [![Build Status](https://secure.travis-ci.org/zerkalica/reactive-di.png)](http://travis-ci.org/zerkalica/reactive-di)\n\n[![NPM](https://nodei.co/npm/reactive-di.png?downloads=true\u0026stars=true)](https://nodei.co/npm/reactive-di/)\n\nTypesafe dependency injection container for react-like components.\n\n* With this DI you can buit pure component based architecture.\n* With this DI you can forget about [HOC](https://reactjs.org/docs/higher-order-components.html) and any decorators around component.\n* Atomatic isolated error and loading status handling for each component.\n* ReactiveDI helps you to follow [open/closed principle](https://en.wikipedia.org/wiki/Open/closed_principle) via slots (like [vue slots](https://vuejs.org/v2/guide/components.html#Content-Distribution-with-Slots)).\n* [Hierarchical Dependency Injectors](https://angular.io/guide/hierarchical-dependency-injection).\n* ReactiveDI easily integrates some state management libraries: [MobX](htttps://mobx.js.org), [lom_atom](https://github.com/zerkalica/lom_atom).\n* Framework agnostic, vendor lock-in free: no static dependencies from React, MobX, etc.\n* Easily integrates css-in-js solutions like [jss](https://github.com/cssinjs/jss).\n* Tiny size about 10kb reactive-di.min.js.\n\n## Links\n\n* [example source](https://github.com/zerkalica/rdi-examples), [demo](http://zerkalica.github.io/rdi-examples/)\n* [todomvc benchmark](http://mol.js.org/app/bench/#bench=https%3A%2F%2Fzerkalica.github.io%2Futb%2Fbenchmark%2F/sample=preact-lom_atom~preact-mobx~preact-raw~preact-reactive-di)\n* [fiddle](https://jsfiddle.net/zerkalica/jxo6hqf8/) example with loading and error handling demo.\n\n## TOC\n\n\u003c!-- TOC depthFrom:2 depthTo:6 withLinks:1 updateOnSave:1 orderedList:0 --\u003e\n\n- [Install](#install)\n- [Debug](#debug)\n- [Hello world](#hello-world)\n\t- [Setup with preact and lom_atom](#setup-with-preact-and-lomatom)\n\t- [Setup with react and mobx](#setup-with-react-and-mobx)\n- [Features](#features)\n\t- [Typesafe context in components](#typesafe-context-in-components)\n\t- [State management based on lom_atom or mobx](#state-management-based-on-lomatom-or-mobx)\n\t- [Automatic error handling](#automatic-error-handling)\n\t- [Custom error handler](#custom-error-handler)\n\t- [Loading status handling](#loading-status-handling)\n\t- [Redefine default dependencies](#redefine-default-dependencies)\n\t- [Components cloning and slots](#components-cloning-and-slots)\n\t- [Hierarchical dependency injection](#hierarchical-dependency-injection)\n\t- [Optional css-in-js support](#optional-css-in-js-support)\n\t- [Multiple css instances](#multiple-css-instances)\n\t- [Passing component props to its depenendencies](#passing-component-props-to-its-depenendencies)\n\t- [React compatible](#react-compatible)\n\t- [Logging](#logging)\n\t- [Map config to objects](#map-config-to-objects)\n- [Credits](#credits)\n\n\u003c!-- /TOC --\u003e\n\n## Install\n\n```\nnpm install --save reactive-di lom_atom babel-plugin-transform-metadata\n```\n\nExample .babelrc:\n\n```json\n{\n    \"presets\": [\n      \"flow\",\n      \"react\",\n      [\"es2015\", {\"loose\": true}]\n    ],\n    \"plugins\": [\n        \"transform-metadata\",\n        \"transform-decorators-legacy\",\n        [\"transform-react-jsx\", {\"pragma\": \"lom_h\"}]\n    ]\n}\n```\n\nbabel-plugin-transform-metadata is optional, used for metadata generation. ReactiveDI use type annotations for dependency resolving, without this plugin you will need to provide metadata manually.\n\n## Debug\n\nBuild rdi and copy to ../app-project/node_modules/reactive-di\n\n```\nnpm run watch --reactive-di:dest=../app-project\n```\n\n## Hello world\n\nReactiveDI has no static dependencies and not a zero-setup library. Setup is usually about 30-50 SLOC, but you do it once per application. But you can integrate into ReactiveDI any component react-like, state management and css-in-js library via adapters.\n\n### Setup with preact and lom_atom\n\n```js\n// @flow\nimport {ReactAtom, mem, action} from 'lom_atom'\nimport {createReactWrapper, createCreateElement} from 'reactive-di'\nimport {render, h, Component} from 'preact'\n\nfunction ErrorableView({error}: {error: Error}) {\n    return \u003cdiv\u003e\n        {!(error instanceof Error)\n            ? \u003cdiv\u003e\n                Loading...\n            \u003c/div\u003e\n            : \u003cdiv\u003e\n                \u003ch3\u003eFatal error !\u003c/h3\u003e\n                \u003cdiv\u003e{error.message}\u003c/div\u003e\n                \u003cpre\u003e\n                    {error.stack.toString()}\n                \u003c/pre\u003e\n            \u003c/div\u003e\n        }\n    \u003c/div\u003e\n}\n\nconst lomCreateElement = createCreateElement(\n    createReactWrapper(\n        Component,\n        ErrorableView,\n        ReactAtom\n    ),\n    (h: React$CreateElement)\n)\nglobal['lom_h'] = lomCreateElement\n```\n\nUsage:\n\n```js\nimport {mem} from 'lom_atom'\nimport {props} from 'reactive-di'\nimport {render} from 'preact'\n\ninterface IHelloProps {\n    name: string;\n}\n\nclass HelloContext {\n    @mem name: string\n    @props set props({name}: IHelloProps) {\n        this.name = name\n    }\n}\n\nexport function HelloView(\n    _: IHelloProps,\n    {context}: {context: HelloContext}\n) {\n    return \u003cdiv\u003e\n        Hello, {context.name}\n        \u003cbr/\u003e\u003cinput value={context.name} onInput={({target}) =\u003e {\n            context.name = (target: any).value\n        }} /\u003e\n    \u003c/div\u003e\n}\nrender(\u003cHelloView name=\"John\" /\u003e, document.body)\n```\n\n### Setup with react and mobx\n\n```js\n// @flow\nimport {Reaction} from 'mobx'\nimport {createReactWrapper, createCreateElement, createMobxReaction} from 'reactive-di'\nimport {createElement, Component} from 'react'\nimport {render} from 'react-dom'\n\nfunction ErrorableView({error}: {error: Error}) {\n    return \u003cdiv\u003e\n        {!(error instanceof Error)\n            ? \u003cdiv\u003e\n                Loading...\n            \u003c/div\u003e\n            : \u003cdiv\u003e\n                \u003ch3\u003eFatal error !\u003c/h3\u003e\n                \u003cdiv\u003e{error.message}\u003c/div\u003e\n                \u003cpre\u003e\n                    {error.stack.toString()}\n                \u003c/pre\u003e\n            \u003c/div\u003e\n        }\n    \u003c/div\u003e\n}\n\nconst lomCreateElement = createCreateElement(\n    createReactWrapper(\n        Component,\n        ErrorableView,\n        createMobxReaction(Reaction)\n    ),\n    createElement\n)\nglobal['lom_h'] = lomCreateElement\n```\n\nUsage:\n\n```js\nimport {observable} from 'mobx'\nimport {props} from 'reactive-di'\nimport {render} from 'preact'\n\ninterface IHelloProps {\n    name: string;\n}\n\nclass HelloContext {\n    @observable name: string\n    @props set props({name}: IHelloProps) {\n        this.name = name\n    }\n}\n\nexport function HelloView(\n    _: IHelloProps,\n    {context}: {context: HelloContext}\n) {\n    return \u003cdiv\u003e\n        Hello, {context.name}\n        \u003cbr/\u003e\u003cinput value={context.name} onInput={({target}) =\u003e {\n            context.name = (target: any).value\n        }} /\u003e\n    \u003c/div\u003e\n}\nrender(\u003cHelloView name=\"John\" /\u003e, document.body)\n```\n\n## Features\n\n### Typesafe context in components\n\nYou can use [context in stateless functional components](https://reactjs.org/docs/context.html#referencing-context-in-stateless-functional-components). With [babel-plugin-transform-metadata](https://github.com/zerkalica/babel-plugin-transform-metadata) you do not need to provide metadata (like ``` Button.contextTypes = {color: PropTypes.string}; ```).\n\nContext signature generated from second argument:\n\n```js\n// @flow\nexport function HelloView(\n    _: IHelloProps,\n    {context}: {context: HelloContext}\n) { ... }\n```\n\nOr\n\n```js\nfunction HelloView(\n  _: {},\n  context: HelloComponent\n) {\n  /// ...\n}\n```\n\nClass definitions used as keys for dependency resolving. For generation dependency metadata ReactiveDI do not use any library (like props-types), raw metadata only expose function arguments to injector. Without plugin, you will need to provide them manually:\n\n```js\nHelloView.deps = [{context: HelloContext}]\n```\n\nInjector in createElement (lom_h) automatically initializes HelloContext and pass it to HelloView in\n\n```js\nrender(\u003cHelloView prefix=\"Hello\" /\u003e, document.body)\n```\n\n### State management based on lom_atom or mobx\n\nReactiveDI is state management agnostic library. You can use mobx or [lom_atom](https://github.com/zerkalica/lom_atom) (like mobx, but much simpler and with some killer features). In ReactiveDI all components are pure functional.\n\n### Automatic error handling\n\nAll errors are isolated in components. They do not breaks whole application. You don't need to manually catch errors via [componentDidCatch](https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html).\n\n```js\nclass HelloContext {\n    @mem get name() {\n      throw new Error('oops')\n    }\n}\n\nfunction HelloView(\n  _: {},\n  {context}: {context: HelloContext}\n) {\n    return \u003cinput value={context.name} onInput={({target}: Event) =\u003e {\n        context.name = (target: any).value\n    }} /\u003e\n}\n```\n\nException in ``` get name ``` intercepted by try/catch in HelloView wrapper and displays by default ErrorableView, registered in ReactiveDI setup:\n\n```js\n// ...\nfunction ErrorableView({error}: {error: Error}) {\n    return \u003cdiv\u003e\n        {!(error instanceof Error)\n            ? \u003cdiv\u003e\n                Loading...\n            \u003c/div\u003e\n            : \u003cdiv\u003e\n                \u003ch3\u003eFatal error !\u003c/h3\u003e\n                \u003cdiv\u003e{error.message}\u003c/div\u003e\n                \u003cpre\u003e\n                    {error.stack.toString()}\n                \u003c/pre\u003e\n            \u003c/div\u003e\n        }\n    \u003c/div\u003e\n}\n\nconst lomCreateElement = createCreateElement(\n    createReactWrapper(\n        Component,\n        ErrorableView,\n        ReactAtom\n    ),\n    h\n)\nglobal['lom_h'] = lomCreateElement\n```\n\n### Custom error handler\n\nYou can provide custom error component handler:\n\n```js\nfunction HelloView(\n  _: {},\n  {context}: {context: HelloContext}\n) {\n    let name: string\n    try {\n      name = context.name\n    } catch (e) {\n      name = 'Error:' + e.message\n    }\n\n    return \u003cinput value={name} onInput={{target}: Event) =\u003e {\n        context.name = (target: any).value\n    }} /\u003e\n}\nHelloView.onError = ({error: Error}) =\u003e (\n    \u003cdiv\u003e{error.message}\u003c/div\u003e\n)\n```\n\nOr manually handle error:\n\n```js\nfunction HelloView(\n  _: {},\n  {context}: {context: HelloContext}\n) {\n    let name: string\n    try {\n      name = context.name\n    } catch (e) {\n      name = 'Error:' + e.message\n    }\n\n    return \u003cinput value={name} onInput={{target}: Event) =\u003e {\n        context.name = (target: any).value\n    }} /\u003e\n}\n```\n\n### Loading status handling\n\nIn ReactiveDI pending/complete status realized via Promise exception.\n\n```js\nfunction ErrorableView({error}: {error: Error | Promise\u003c*\u003e}) {\n    return \u003cdiv\u003e\n        {!(error instanceof Error)\n            ? \u003cdiv\u003e\n                Loading...\n            \u003c/div\u003e\n            : ...\n        }\n    \u003c/div\u003e\n}\n```\n\nIn component model ``` throw new Promise() ``` catched in HelloComponent wrapper and default ErrorableView shows ``` Loading... ``` instead of HelloView.\n\n```js\nclass HelloContext {\n    @mem set name(next: string | Error) {}\n    @mem get name(): string {\n        // fetch some data and update name\n        throw new AtomWait()\n    }\n}\n```\n\nOn fetch complete ``` fetch().then((data: string) =\u003e {this.name = data}) ``` sets new data and render HelloView instead of ErrorableView.\n\n### Redefine default dependencies\n\nClass SomeAbstract used somewhere in the application, but at ReactiveDI setup you can redefine them to SomeConcrete class instance with same interface.\n\n```js\nclass SomeAbstract {}\n\nclass SomeConcrete extends SomeAbstract {}\n\nclass C {\n  a: SomeAbstract\n  constructor(a: SomeAbstract) {\n    this.a = a\n  }\n}\n\nconst injector = new Injector(\n    [\n      [SomeAbstract, new SomeConcrete()]\n    ]\n)\n\ninjector.value(SomeAbstract).a instanceof SomeConcrete\n```\n\n### Components cloning and slots\n\nIn vue you can use [content distribution with slots](https://vuejs.org/v2/guide/components.html#Content-Distribution-with-Slots). ReactiveDI helps you to do same thing in react-applications. Slot is a component itself or its id.\n\nCreate slightly modified component, based on FirstCounterView.\n\n```js\nimport {cloneComponent} from 'reactive-di'\nclass FirstCounterService {\n  @mem value = 0\n}\n\nfunction CounterMessageView({value}: {value: string}) {\n  return \u003cdiv\u003ecount: {value}\u003c/div\u003e\n}\n\nfunction FirstCounterView(\n    _: {},\n    counter: FirstCounterService\n) {\n    return \u003cdiv\u003e\n        \u003cCounterMessageView value={counter.value}/\u003e\n        \u003cbutton id=\"FirstCounterAddButton\" onClick={() =\u003e { counter.value++ }}\u003eAdd\u003c/button\u003e\n    \u003c/div\u003e\n}\n\nclass SecondCounterService {\n  @mem value = 1\n}\n\n// Create FirstCounterView copy, but remove FirstCounterAddButton and replace FirstCounterService to SecondCounterService.\n\nconst SecondCounterView = cloneComponent(FirstCounterView, [\n    [FirstCounterService, SecondCounterService],\n    ['FirstCounterAddButton', null],\n], 'SecondCounterView')\n```\n\nWorks like inheritance in classes, but you don't need to extract each component detail in methods. Any component part is open for extension bу default. Be careful, do not violate [Liskov substitution principle](https://en.wikipedia.org/wiki/Liskov_substitution_principle).\n\n### Hierarchical dependency injection\n\nEach component instance has an own injector. Injector - is a type to instance map, which types described in component context.\n\nWhen Parent and Child components depends on on same SharedService - DI injects one instance to them. And this instance live while Parent component mounted to DOM.\n\n```js\nclass SharedService {}\nfunction Parent(\n  props: {},\n  context: {sharedService: SharedService}\n) {\n  return \u003cChild parentService={context.sharedService} /\u003e\n}\n\nfunction Child(\n  _: {},\n  context: {sharedService: SharedService}\n) {\n  // context.sharedService instance cached in parent\n}\n```\n\nIf only Child component depends on SharedService, DI creates separated SharedService instance per Child.\n\n```js\nclass SharedService {}\nfunction Parent() {\n  return \u003cChild/\u003e\n}\n\nfunction Child(\n  props: {},\n  context: {sharedService: SharedService}\n) {\n  // sharedService - cached in child\n}\n```\n\n### Optional css-in-js support\n\nCss-in-js with reactivity and dependency injection power. ReactiveDI not statically depended on [Jss](https://github.com/cssinjs/jss), you can integrate another css-in-js solution, realizing described below interface.\n\nSetup:\n\n```js\n// @flow\nimport {ReactAtom, mem, defer} from 'lom_atom'\nimport {JssSheetManager, createReactWrapper, createCreateElement, Injector} from 'reactive-di'\n\nimport {h, Component} from 'preact'\nimport {create as createJss} from 'jss'\n\nimport ErrorableView from './ErrorableView'\n\nconst jss = new JssSheetManager(createJss(), defer.add)\n/*\njss must implements IProcessor interface:\n\nexport interface IProcessor {\n    createStyleSheet\u003cV: Object\u003e(_cssObj: V, options: any): ISheet\u003cV\u003e;\n}\n\nexport interface ISheet\u003cV: Object\u003e {\n    attach(): ISheet\u003cV\u003e;\n    classes: {+[id: $Keys\u003cV\u003e]: string};\n}\n*/\nconst lomCreateElement = createCreateElement(\n    createReactWrapper(\n        Component,\n        ErrorableView,\n        ReactAtom,\n        new Injector([], jss)\n    ),\n    h\n)\nglobal['lom_h'] = lomCreateElement\n```\n\nReactive style usage:\n\n```js\nimport {mem} from 'lom_atom'\nimport {theme} from 'reactive-di'\n\nclass ThemeVars {\n  @mem color = 'red'\n}\n\nclass MyTheme {\n    vars: ThemeVars\n    constructor(vars: ThemeVars) {\n        this._vars = vars\n    }\n\n    @mem @theme get css() {\n        return {\n            wrapper: {\n                backgroundColor: this._vars.color\n            }\n        }\n    }\n}\n\nfunction MyView(\n  props: {},\n  {theme: {css}, vars}: {theme: MyTheme, vars: ThemeVars}\n) {\n  return \u003cdiv class={css.wrapper}\u003e...\n    \u003cbutton onClick={() =\u003e vars.color = 'green'}\u003eChange color\u003c/button\u003e\n  \u003c/div\u003e\n}\n```\n\nStyles automatically mounts/unmounts together with component. Changing ``` vars.color ``` automatically rebuilds and remounts css.\n\nWith mobx, unmount feature does not works at current moment. But still no memory leaks, due to unique theme id.\n\nWithout any state management library works only css mounting without reactivity updates.\n\n```js\nimport {theme} from 'reactive-di'\nclass MyTheme {\n    @theme get css() {\n        return {\n            wrapper: {\n                backgroundColor: 'red'\n            }\n        }\n    }\n}\n\nfunction MyView(\n  props: {},\n  {theme: {css}, vars}: {theme: MyTheme}\n) {\n  return \u003cdiv class={css.wrapper}\u003e...\u003c/div\u003e\n}\n```\n\n### Multiple css instances\n\nBy default one css block generated per component. But you can generate unique css block per component instance too. Just use ``` theme.self ``` decorator:\n\n```js\nimport {mem} from 'lom_atom'\nimport {props, theme} from 'reactive-di'\n\ninterface MyProps {\n    color: string;\n}\n\nclass MyTheme {\n    @mem @props _props: MyProps\n    @mem @theme.self get css() {\n        return {\n            wrapper: {\n                backgroundColor: this.props.color\n            }\n        }\n    }\n}\n\nfunction MyView(\n  props: MyProps,\n  {theme: {css}}: {theme: MyTheme}\n) {\n  return \u003cdiv class={css.wrapper}\u003e...\n  \u003c/div\u003e\n}\n\n\u003cMyView color=\"red\"/\u003e\n\u003cMyView color=\"blue\"/\u003e\n```\n\n### Passing component props to its depenendencies\n\nYou can pass component properties to its dependencies via ``` prop ``` decorator.\n\n```js\nimport {mem} from 'lom_atom'\nimport {props} from 'reactive-di'\n\ninterface MyProps {\n  some: string;\n}\n\nclass MyViewService {\n  @props _props: MyProps;\n  // @mem @props _props: MyProps; // for reactive props\n  @mem get some(): string {\n    return this._props.some + '-suffix'\n  }\n}\n\nfunction MyView(\n  props: MyProps,\n  {service}: {service: MyViewService}\n) {\n  return \u003cdiv\u003e{service.some}\u003c/div\u003e\n}\n```\n\nIf you need to react on props changes - just use combination ``` @mem ``` and ``` @props ``` decorators.\n\n```js\nclass MyViewService {\n  @mem @props _props: MyProps;\n  // @mem @props _props: MyProps; // for reactive props\n  @mem get some(): string {\n    return this._props.some + '-suffix'\n  }\n}\n```\n\n### React compatible\n\nYou can use any react/preact/inferno components together with rdi components.\n\n### Logging\n\nNot ReactiveDI part, in state management libraries you can monitor state changes and user actions.\n\nConsole logger in lom_atom:\n\n```js\nimport {defaultContext, BaseLogger, ConsoleLogger} from 'lom_atom'\nimport type {ILogger} from 'lom_atom'\n\ndefaultContext.setLogger(new ConsoleLogger())\n```\n\nFor custom loggers, implement [interface ILogger](https://github.com/zerkalica/lom_atom/blob/master/src/interfaces.js#L9).\n\n### Map config to objects\n\nExperimental feature - you can restore state on client side by providing data to class map in Injector.\n\n```js\n// @flow\nimport {mem} from 'lom_atom'\nimport {Injector} from 'reactive-di'\n\nconst defaultDeps = []\nconst injector = new Injector([], undefined, {\n    SomeService: {\n        name: 'test',\n        id: 123\n    }\n})\n\nclass SomeService {\n    // setup babel-plugin-transform-metadata or define displayName, if js-uglify used\n    static displayName = 'SomeService'\n    @mem name = ''\n    id = 0\n}\n\nconst someService: SomeService = injector.value(SomeService)\n\nsomeService.name === 'test'\nsomeService.id === 123\n```\n\ndisplayName in class used as a key for data mapping. [babel-plugin-transform-metadata](https://github.com/zerkalica/babel-plugin-transform-metadata) can generate displayName. To enable it, add ``` [\"transform-metadata\", {\"addDisplayName\": true}] ``` into .babelrc.\n\nExample .babelrc:\n\n```json\n{\n    \"presets\": [\n      \"flow\",\n      \"react\",\n      [\"es2015\", {\"loose\": true}]\n    ],\n    \"plugins\": [\n        [\"transform-metadata\", {\"addDisplayName\": true}],\n        \"transform-decorators-legacy\",\n        [\"transform-react-jsx\", {\"pragma\": \"lom_h\"}]\n    ]\n}\n```\n\n## Credits\n* [mol](https://github.com/eigenmethod/mol) OORP ideas\n* [Ninject](https://github.com/ninject/Ninject) best dependency injector, writen in C#.\n* [inversify.io](http://inversify.io/) nice try of reimplementing Ninject in typescript.\n* [angular2](https://angular.io) ideas of hierarchical injectors.\n* [babel-plugin-angular2-annotations](https://github.com/shuhei/babel-plugin-angular2-annotations) ideas of metadata for resolving dependencies.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzerkalica%2Freactive-di","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzerkalica%2Freactive-di","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzerkalica%2Freactive-di/lists"}