UNPKG

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