UNPKG

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