-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
154 additions
and
133 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters