From 8ff358e4b2621db72d97f25aa35e6b632491d2b4 Mon Sep 17 00:00:00 2001 From: betula Date: Wed, 26 Jun 2019 12:33:33 +0800 Subject: [PATCH] Update readme common description --- README.md | 170 +++++++++++++++++++++++++++++++++++++++++++++------ README.ru.md | 112 --------------------------------- package.json | 5 +- 3 files changed, 154 insertions(+), 133 deletions(-) delete mode 100644 README.ru.md diff --git a/README.md b/README.md index 20ad466..b56665e 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,172 @@ +# node-provide [![npm version](https://badge.fury.io/js/node-provide.svg)](https://badge.fury.io/js/node-provide) [![Build Status](https://travis-ci.org/betula/node-provide.svg?branch=master)](https://travis-ci.org/betula/node-provide) [![Coverage Status](https://coveralls.io/repos/github/betula/node-provide/badge.svg?branch=master)](https://coveralls.io/github/betula/node-provide?branch=master) +Minimalistic Dependency Injection for Node.JS -node-provide is more than simple decorator for control your dependencies. It's a powerful instrument for organizing the architecture of your application. +- You can use it in any place of your application without rewrite your applications architecture or other preparations or initializations. +- Each dependency can be class, function, or any another value, and plain JavaScript object of cource too. +- You can override your dependencies for organize modules architecture, or unit testing without pain with replace standart Node.JS require mechanism. +- You can use TypeScript or JavaScript, with decorators or not. +- Defferent syntaxies for one mechanism. You can use constructor for provide dependencies or not, as you wish. +- You can create isolate context for multiple instances of you application with different set of depenencies, overrides and instances. -The better experience you will get if you use node-provide with TypeScript because in this case, you can get an instance of your dependency with 9 character instruction. +## Install -I recommend to split all code of your project into three different types: -1. Library. It's a code who doesn't need any dependencies from your application. Drivers for databases or crypto hash creators or something else what you can find in npm. -2. Services. It's a code split by classes and any other structures. We need each of the services in one instance. For example, configured database connection pool or configured express server or it can be a factory of anything. -3. Other code born through decomposition or as a normal process throw application grown up. +``` +npm install node-provide +``` + +## Some examples for different syntax and JavaScript preprocessors. -node-provide helps to you use a single instance of any class with zero parameters in constructor at any place of your application. Usually this type of abstraction named service. +TypeScript with decorators and reflect metadata -Each class provided through node-provide do instantiate only on demand in first access to it. +```TypeScript +import { provide, inject } from "node-provide"; +// ... -```ts -import { provide } from "node-provide"; +class Db { /* ... */ } +class Server { /* ... */ } +class AccountRouter { /* ... */ } +// ... -class Hello { - public send(text: string) { - console.log(`Hello ${text}`); +// Inject dependencies using @provide decorator and class properties +export default class App { + @provide db: Db; + @provide server: Server; + @provide accountRouter: AccountRouter; + // ... + start() { + this.db.init(); + // ... } } -class App { - @provide public hello: Hello; +// or using @inject decorator and constructor parameters +@inject +export default class App { + constructor( + public db: Db, + public server: Server, + public accountRouter: AccountRouter, + ) { /* ... */ } + // ... +} +``` + +JavaScript with decorators + +```JavaScript +import { provide, inject } from "node-provide"; +// ... + +// Using @provide decorator +export default class App { + @provide(Db) db; + @provide(Server) server; + @provide(AccountRouter) accountRouter; + // ... + start() { + this.db.init(); + // ... + } +} + +// or using @inject decorator +@inject({ + db: Db, + server: Server, + accountRouter: AccountRouter, +}) +export default class App { + start() { + this.db.init(); + // ... + } + // ... +} +``` + +Pure JavaScript without decorators + +```JavaScript +const { inject, attach, container } = require("node-provide"); +// ... + +const Db = require("./db"); +const Server = require("./server"); +const AccountRouter = require("./account-router"); +// ... + +const services = container({ + db: Db, + server: Server, + accountRouter: AccountRouter, +}); + +// Using in function +module.exports = function() { + return { + start() { + services.db.init(); + // ... + }, + // ... + } +} + +// or using attach to `this` in constructor +module.exports = class App { constructor() { - this.hello.send("world!"); + attach(this, { + db: Db, + server: Server, + accountRouter: AccountRouter, + }); + } + // ... + start() { + this.db.init(); + // ... } } -const app = new App(); +// or using inject decorator +class App { + start() { + this.db.init(); + // ... + } + // ... +} +module.exports = inject(services)(App); ``` -You can see a graceful example of server for RESTful API in examples folder inside this ([repository](https://github.com/betula/node-provide/tree/master/examples/api-server-with-jest)). +## Unit testing + + +## API Reference + +**inject** + +**provide** + +**resolve** + +**container** + +**attach** + +**bind** + +**override** + +**assign** + +**isolate** + + +--- -If you have questions or something else for me or this project. Maybe architectures questions, improvement ideas or anything else. Please make issues. I want to continue to develop this project and each of your opinions and thoughts will be grateful. +If you have questions or something else for me or this project, maybe architectures questions, improvement ideas or anything else, please make issues. diff --git a/README.ru.md b/README.ru.md deleted file mode 100644 index d0815b2..0000000 --- a/README.ru.md +++ /dev/null @@ -1,112 +0,0 @@ -# node-provide -[![npm version](https://badge.fury.io/js/node-provide.svg)](https://badge.fury.io/js/node-provide) -[![Build Status](https://travis-ci.org/betula/node-provide.svg?branch=master)](https://travis-ci.org/betula/node-provide) -[![Coverage Status](https://coveralls.io/repos/github/betula/node-provide/badge.svg?branch=master)](https://coveralls.io/github/betula/node-provide?branch=master) - -Библиотека для внедрения зависимостей. Позволяет легко поставлять инстанцированные в единственном экземпляре зависимости в любую точку важего приложения без необходимости предварительного проектирования архитектуры приложения под использование привычных механизмов внедрения зависимостей. - -Каждая зависимостей определяется как класс без параметров в конструкторе, либо функция без аргументов. Наиболее удобным является использование декоратора `provide` в TypeScript, но так же поддерживает приятный синтаксис и для JavaScript как с использованием декораторов, так и без них, в случае использования "чистой" Node.JS без каких-либо препроцессоров кода. В качестве идентификатора для зависимости используется класс или функция её определяющая. - -Пример использования в TypeScript -```TypeScript -import { provide } from "node-provide"; - -class Server { - public configure(port: number = 80, hostname?: string) { - //... - } - public route(pattern: string, callback: (req: Request, res: Response) => void) { - //... - } - public start() { - //... - } -} - -class IndexController { - // Использование декоратора `provide`, - // теперь инстанция класса Server доступна через `this.server`. - @provide server: Server; - public mount() { - this.server.route("/", this.index.bind(this)); - } - public index(req: Request, res: Response) { - res.send("index"); - } -} - -class App { - @provide server: Server; - @provide indexController: IndexController; - public start() { - this.server.configure(); - this.indexController.mount(); - this.server.start(); - } -} -``` - -Не забудьте включить опцию `emitDecoratorMetadata` в вашем `tsconfig.json` файле. Так же будет необходимо отключить опцию `strictPropertyInitialization`, так как TypeScript на данный момент не умеет вычислять преобразование поля класса в геттер через декоратор и считает такие поля не инициализированными и будет ошибочно "требовать" их инициализации в конструкторе. - -На JavaScript с использованием декораторов использование `provide` будет выглядеть так: - -```JavaScript -import { provide } from "node-provide"; - -class Server { - start() { - //... - } -} - -class App { - // Здесь используется декоратор `provide`, - // где первым аргументом передан класс зависимости. - @provide(Server) server; - start() { - this.server.start(); - } -} -``` - -Так же можно описать зависимость через функцию возвращающую объект с набором методов для работы с ней. Тут декораторы уже не потребуется, что значит можно использовать "чистый" Node.JS без каких-либо преобразований. - -```JavaScript -// app.js -const { container } = require("node-provide"); -const Server = require("./server"); -const IndexController = require("./index-controller"); - -const services = container({ - server: Server, - indexController: IndexController, -}); - -module.exports = function() { - //... - return { - start() { - services.server.configure(); - services.indexController.mount(); - } - } -} - -// Если вам не нужно определять `App` как зависимость, -// то можете создать его инстанцию явно. -// index.js -const App = require("./app"); -new App().start(); - -// Если же вы хотите, что бы `App` был полноценной зависимостью, -// доступной в любой точке приложения, -// то можете инстанцировать его через `resolve`. -// index.js -const { resolve } = require("node-provide"); -const App = require("./app"); -resolve(App).start(); -``` - -Есть ещё несколько вариантов поставить зависимости, отличающиеся друг от друга синтаксически. - - diff --git a/package.json b/package.json index 4a7c3c8..1cfcfcc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-provide", - "version": "0.2.0", - "description": "Simple dependency provider for node", + "version": "0.2.1", + "description": "Minimalistic Dependency Injection for Node.JS", "repository": { "url": "https://github.com/betula/node-provide" }, @@ -20,6 +20,7 @@ "dependency provider", "provide", "injection", + "inject", "node" ], "author": "Viacheslav Bereza ",