1 | # di-corate
|
2 | Another 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
|
12 | Use the library to engage the Dependency Injection in your project.
|
13 | The 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
|
21 | import { Injectable } from 'di-corate';
|
22 |
|
23 | @Injectable()
|
24 | export class Service1 {
|
25 | do() {}
|
26 | }
|
27 | ```
|
28 |
|
29 | **service2.ts**
|
30 | ```javascript
|
31 | import { Injectable } from 'di-corate';
|
32 |
|
33 | @Injectable()
|
34 | export class Service2 {
|
35 | run() {}
|
36 | }
|
37 | ```
|
38 |
|
39 | **component.ts**
|
40 | ```javascript
|
41 | import { Injectable, Inject } from 'di-corate';
|
42 |
|
43 | @Injectable()
|
44 | export 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
|
64 | import { Injectable } from 'di-corate';
|
65 |
|
66 | @Injectable()
|
67 | export class HttpClient {
|
68 | get(url: string) { return 'response'; }
|
69 | }
|
70 | ```
|
71 |
|
72 | **service.ts**
|
73 | ```javascript
|
74 | import { Injectable, Inject } from 'di-corate';
|
75 |
|
76 | @Injectable()
|
77 | export 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
|
89 | import { Injectable, Inject } from 'di-corate';
|
90 |
|
91 | @Injectable()
|
92 | export 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
|
104 | Its possible to configure instance lifecycle for each injectale type.
|
105 |
|
106 | ###### Examples
|
107 |
|
108 | ```javascript
|
109 | import { Injectale, InjectionScopeEnum } from 'di-corate';
|
110 |
|
111 | // Injects as singletone instance.
|
112 | @Injectale()
|
113 | export class SomeSingletone {
|
114 | abstract run(): void;
|
115 | }
|
116 |
|
117 | // Injects as singletone instance.
|
118 | @Injectale({
|
119 | scope: InjectionScopeEnum.Singletone
|
120 | })
|
121 | export class OtherSingletone {
|
122 | abstract run(): void;
|
123 | }
|
124 |
|
125 | // Injects as transient instance.
|
126 | @Injectale({
|
127 | scope: InjectionScopeEnum.Transient
|
128 | })
|
129 | export 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 |
|
157 | The 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
|
182 | export abstract class Service {
|
183 | abstract run(): void;
|
184 | }
|
185 | ```
|
186 |
|
187 | **default-service.ts**
|
188 | ```javascript
|
189 | import { Injectale } from 'di-corate';
|
190 |
|
191 | @Injectale()
|
192 | export class DefaultService implements Service {
|
193 | run() {
|
194 | console.log('Implementation');
|
195 | };
|
196 | }
|
197 | ```
|
198 |
|
199 | **component.ts**
|
200 | ```javascript
|
201 | import { provide, Injectable, Inject } from 'di-corate';
|
202 | import { DefaultService } from 'default-service';
|
203 |
|
204 | provide(Service, DefaultService);
|
205 |
|
206 | @Injectale()
|
207 | export 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 |