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