1 | # Azera Container
|
2 |
|
3 | - [Intro](##Intro)
|
4 | - [Property Injection](##Property%20Injection)
|
5 | - [Container-aware class](##Container-aware%20class)
|
6 | - [Factory](##Factory)
|
7 | - [Tags](##Tags)
|
8 | - [Auto tagging](##Auto%20tagging)
|
9 | - [Create custom auto tagging function](###Create%20custom%20auto%20tagging%20function)
|
10 | - [Predefined Services and Parameters](##Predefined%20Services%20and%20Parameters)
|
11 | - [Type-based injection](##Type-based%20injection)
|
12 | - [Async](#Async)
|
13 |
|
14 | ## Intro
|
15 | Azera container is a `dependency injection` service container for `JavaScript` written in `Typescript`.
|
16 |
|
17 | First simple example :
|
18 | ```javascript
|
19 | import {Container} from "@azera/container";
|
20 |
|
21 | let container = new Container;
|
22 |
|
23 | container.set('logger', class Logger {
|
24 | log(message) {}
|
25 | })
|
26 |
|
27 | let app = container.invoke(['logger', class App {
|
28 | constructor(logger) {
|
29 | logger.log('Initialize app');
|
30 | }
|
31 | }]);
|
32 | ```
|
33 |
|
34 | Simple injection with decorators in Typescript :
|
35 | ```typescript
|
36 | import {Service, Container} from "@azera/container";
|
37 |
|
38 | class Logger {
|
39 | @Inject('loggerNS') namespace: string;
|
40 | log(message) { console.log(`[${this.namespace}] ${message}`); }
|
41 | }
|
42 |
|
43 | @Inject([ Logger ]) class App {
|
44 | constructor(private logger: Logger) {}
|
45 | init() { this.logger.log('Initailize application'); }
|
46 | }
|
47 |
|
48 | let container = new Container();
|
49 | // Set a parameter
|
50 | container.setParameter('loggerNS', 'app');
|
51 | // Create an instance from App
|
52 | let app = container.invoke(App);
|
53 | app.init();
|
54 | // Console output : "[app] Initialize application"
|
55 | ```
|
56 |
|
57 | ## Property injection
|
58 | ```typescript
|
59 | class App {
|
60 | @Inject('logger') logger: Logger;
|
61 | }
|
62 | ```
|
63 | Simply !
|
64 |
|
65 | ## Container-aware class
|
66 | ```typescript
|
67 | import {ContainerAware, Container} from "@azera/container";
|
68 |
|
69 | @Service('logger') class Logger {
|
70 | log(message) { console.log(message); }
|
71 | }
|
72 |
|
73 | class App extends ContainerAware() {
|
74 | init() {
|
75 | this.container.get('logger').log('Initialize app');
|
76 | }
|
77 | }
|
78 |
|
79 | let container = new Container();
|
80 | container.add(Logger);
|
81 | let app = container.invoke(App);
|
82 | app.init(); // output: Initialize app
|
83 | ```
|
84 |
|
85 | ## Factory
|
86 | You can also use factories to generate services, only add Factory to the end of function name :
|
87 | ```typescript
|
88 | import {Container} from "@azera/container";
|
89 |
|
90 | class Logger {
|
91 | log() {}
|
92 | }
|
93 |
|
94 | container.set('logger', function loggerFactory() {
|
95 | return new Logger;
|
96 | });
|
97 |
|
98 | let logger: Logger = container.get('logger');
|
99 | // Or
|
100 | let logger = container.get<Logger>('logger');
|
101 | ```
|
102 |
|
103 | ## Tags
|
104 | Also you can define tag for services :
|
105 | ```typescript
|
106 | import {Container, Tag} from "@azera/container";
|
107 |
|
108 | abstract class Command { }
|
109 |
|
110 | @Tag('command') class RunCommand extends Command {}
|
111 | @Tag('command') class HelpCommand extends Command {}
|
112 |
|
113 | let container = new Container;
|
114 | container.add(RunCommand, HelpCommand);
|
115 |
|
116 | let commands: Command[] = container.getByTag<Command>('command');
|
117 | // Or inject them
|
118 | class ConsoleApp {
|
119 | @Inject('$$command') commands: Command[];
|
120 | }
|
121 | ```
|
122 |
|
123 | ### Auto tagging
|
124 | You can do tagging automatically :
|
125 | ```typescript
|
126 | import {Container} from "@azera/container";
|
127 |
|
128 | abstract class Command { }
|
129 |
|
130 | class RunCommand extends Command {}
|
131 | class HelpCommand extends Command {}
|
132 |
|
133 | container
|
134 | .autoTag(Command, [ 'command' ])
|
135 | .add(RunCommand, HelpCommand);
|
136 |
|
137 | class ConsoleApp {
|
138 | @Inject('$$command') commands: Command[];
|
139 | }
|
140 |
|
141 | let app = container.invoke(ConsoleApp);
|
142 | ```
|
143 |
|
144 | #### Create custom auto tagging function
|
145 | ```typescript
|
146 | container.autoTag( definition => {
|
147 | return definition.name.endsWith('Command') ? ['command'] : []
|
148 | })
|
149 | ```
|
150 |
|
151 | ## Predefined Services and Parameters
|
152 | ```typescript
|
153 | // services.ts
|
154 | import {Inject} from "@azera/container";
|
155 |
|
156 | export default {
|
157 |
|
158 |
|
159 | app: class App {
|
160 |
|
161 | @Inject('logger')
|
162 | logger: Logger;
|
163 |
|
164 | run() {
|
165 | // Run logic
|
166 | }
|
167 |
|
168 | },
|
169 |
|
170 | // You can also declare service with Definition schema
|
171 | logger: {
|
172 | service: class Logger {
|
173 | constructor(private ns: string) {}
|
174 | },
|
175 | parameters: [ '$loggerNS' ]
|
176 | }
|
177 | }
|
178 | ```
|
179 | ```typescript
|
180 | // parameters.ts
|
181 | export default {
|
182 | loggerNS: 'app'
|
183 | }
|
184 | ```
|
185 | ```typescript
|
186 | // index.ts
|
187 | import {Container} from "@azera/container";
|
188 | import Services from "./services";
|
189 | import Parameters from "./parameters";
|
190 |
|
191 | let container = new Container(Services, Parameters);
|
192 | let app = container.get('app');
|
193 | app.run();
|
194 | ```
|
195 |
|
196 |
|
197 | ## Type-based injection
|
198 | We can also emit service configuration and naming and use type-based injection.
|
199 |
|
200 | ```typescript
|
201 | // Logger.ts
|
202 | export default class Logger {
|
203 | log(message: string) {
|
204 | console.log(message);
|
205 | }
|
206 | }
|
207 | ```
|
208 | ```typescript
|
209 | // App.ts
|
210 | import Logger form './Logger.ts'
|
211 |
|
212 | export default class App {
|
213 | constructor(@Inject() public logger: Logger) {}
|
214 | }
|
215 | ```
|
216 | ```typescript
|
217 | // index.ts
|
218 | import App from './App.ts';
|
219 |
|
220 | new Container()
|
221 | .invoke(App)
|
222 | .logger
|
223 | .log('Hello World');
|
224 | ```
|
225 |
|
226 |
|
227 | ## Async
|
228 | ```typescript
|
229 | @Service({
|
230 | factory: async function connectionFactory() {
|
231 | let connection = new Connection();
|
232 | await connection.connect();
|
233 | return connection;
|
234 | }
|
235 | })
|
236 | class Connection {
|
237 | name = "default";
|
238 | async connect() { /** Connection logic **/ }
|
239 | async execute(query: string) { /** Command Exection **/ }
|
240 | }
|
241 |
|
242 | class Model {
|
243 | constructor(@Inject() connection: Connection) {
|
244 | }
|
245 | }
|
246 |
|
247 | let container = new Container();
|
248 | container.invokeAsync(Model).then(model => {
|
249 | console.log(model.connection.execute("SELECT * FROM User"));
|
250 | });
|
251 | ``` |
\ | No newline at end of file |