UNPKG

4.91 kBMarkdownView Raw
1# di-corate
2Another dependency injection implementation for Typescript using decorators.
3
4[![Build Status](https://travis-ci.com/apashkov-ext/di-corate.svg?branch=main)](https://travis-ci.com/apashkov-ext/di-corate)
5[![npm version](https://img.shields.io/npm/v/di-corate)](https://www.npmjs.com/package/di-corate)
6[![install size](https://packagephobia.now.sh/badge?p=di-corate)](https://packagephobia.now.sh/result?p=di-corate)
7[![Coverage Status](https://coveralls.io/repos/github/apashkov-ext/di-corate/badge.svg?branch=main)](https://coveralls.io/github/apashkov-ext/di-corate?branch=main)
8[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/git/git-scm.com/blob/master/MIT-LICENSE.txt)
9
10## Installation
11`npm install di-corate`
12## Using
13Use the library to engage the Dependency Injection in your project.
14The library does not use the `reflect-metadata` package. The library supports two ways of dependency injection:
15- **class property**
16- **constructor parameter**
17
18### Simple DI
19
20**service1.ts**
21```javascript
22import { Injectable } from 'di-corate';
23
24@Injectable()
25export class Service1 {
26 do() {}
27}
28```
29
30**service2.ts**
31```javascript
32import { Injectable } from 'di-corate';
33
34@Injectable()
35export class Service2 {
36 run() {}
37}
38```
39
40**component.ts**
41```javascript
42import { Injectable, Inject } from 'di-corate';
43
44@Injectable()
45export class Component {
46 // Inject into property.
47 @Inject(Service1) private readonly srv1: Service1;
48
49 // Inejct into constuctor parameter.
50 constructor(@Inject(Service2) private readonly srv2: Service2) {
51 srv2.do();
52 example();
53 }
54
55 private example() {
56 this.srv1.run();
57 }
58}
59```
60
61#### Dependency tree
62
63**http-client.ts**
64```javascript
65import { Injectable } from 'di-corate';
66
67@Injectable()
68export class HttpClient {
69 get(url: string) { return 'response'; }
70}
71```
72
73**service.ts**
74```javascript
75import { Injectable, Inject } from 'di-corate';
76
77@Injectable()
78export class Service {
79 constructor(@Inject(HttpClient) private readonly http: HttpClient) { }
80
81 do() {
82 const resp = this.http.get('someUrl');
83 console.log(resp);
84 }
85}
86```
87
88**component.ts**
89```javascript
90import { Injectable, Inject } from 'di-corate';
91
92@Injectable()
93export class Component {
94 constructor(@Inject(Service) private readonly srv: Service) {
95 example();
96 }
97
98 private example() {
99 this.srv.do();
100 }
101}
102```
103
104### Instance lifetime configuring
105Its possible to configure instance lifecycle for each injectale type.
106
107###### Examples
108
109```javascript
110import { Injectale, InjectionScopeEnum } from 'di-corate';
111
112// Injects as singletone instance.
113@Injectale()
114export class SomeSingletone {
115 abstract run(): void;
116}
117
118// Injects as singletone instance.
119@Injectale({
120 scope: InjectionScopeEnum.Singletone
121})
122export class OtherSingletone {
123 abstract run(): void;
124}
125
126// Injects as transient instance.
127@Injectale({
128 scope: InjectionScopeEnum.Transient
129})
130export class SomeClass {
131 abstract run(): void;
132}
133```
134
135###### Explanation
136<table>
137<thead>
138 <tr>
139 <th>Injection scope</th>
140 <th>Instance sharing</th>
141 </tr>
142</thead>
143<tbody>
144 <tr>
145 <td>Singletone (uses by default)</td>
146 <td>One instance for the whole application</td>
147 </tr>
148 <tr>
149 <td>Transient</td>
150 <td>Dedicated instance for each consumer</td>
151 </tr>
152</tbody>
153</table>
154
155###### Time of instantiation
156
157
158The moment in time when the dependency instance will be created depends on the chosen dependency injection way.
159
160<table>
161<thead>
162 <tr>
163 <th>Injection target</th>
164 <th>Instantiation time</th>
165 </tr>
166</thead>
167<tbody>
168 <tr>
169 <td>Class property</td>
170 <td>On first access to the property</td>
171 </tr>
172 <tr>
173 <td>Constructor parameter</td>
174 <td>During class instantiation</td>
175 </tr>
176</tbody>
177</table>
178
179### Custom provider setup
180
181**service.ts**
182```javascript
183export abstract class Service {
184 abstract run(): void;
185}
186```
187
188**default-service.ts**
189```javascript
190import { Injectale } from 'di-corate';
191
192@Injectale()
193export class DefaultService implements Service {
194 run() {
195 console.log('Implementation');
196 };
197}
198```
199
200**component.ts**
201```javascript
202import { provide, Injectable, Inject } from 'di-corate';
203import { DefaultService } from 'default-service';
204
205provide(Service, DefaultService);
206
207@Injectale()
208export class Component {
209 constructor(@Inject('Service') private readonly srv: Service) {
210 example();
211 }
212
213 private example() {
214 // Console: 'Implementation'.
215 this.srv.run();
216 }
217}
218```
219## Road map
220<table>
221<tbody>
222 <tr>
223 <td>Singletone injection scope</td>
224 <td>✅</td>
225 </tr>
226 <tr>
227 <td>Transient</td>
228 <td>✅</td>
229 </tr>
230 <tr>
231 <td>String injection token</td>
232 <td>❌</td>
233 </tr>
234 <tr>
235 <td>Multiple dependencies for single token (array of instances)</td>
236 <td>❌</td>
237 </tr>
238</tbody>
239</table>
\No newline at end of file