1
+ # Dependency injection
2
+ Dependency injection for Go programming language.
3
+
4
+ Dependency injection is one form of the broader technique of inversion of control. It is used to increase modularity of the program and make it extensible.
5
+
6
+ ## Examples
7
+ ``` go
8
+ type A struct {
9
+ Name string
10
+ }
11
+
12
+ func NewA () *A {
13
+ r := rand.New (rand.NewSource (time.Now ().UnixNano ()))
14
+ name := " A-" + strconv.Itoa (r.Int ())
15
+ return &A{Name: ls}
16
+ }
17
+
18
+ services := NewServiceCollection ()
19
+ services.AddSingleton (NewA)
20
+ // serviceCollection.AddSingletonByImplementsAndName("redis-master", NewRedis, new(abstractions.IDataSource))
21
+ // serviceCollection.AddTransientByImplements(NewRedisClient, new(redis.IClient))
22
+ // serviceCollection.AddTransientByImplements(NewRedisHealthIndicator, new(health.Indicator))
23
+ serviceProvider := services.Build ()
24
+
25
+ var env *A
26
+ _ = serviceProvider.GetService (&env) // used
27
+ ```
28
+
1
29
## How will dependency injection help me?
2
30
3
31
Dependency injection is one form of the broader technique of inversion
@@ -26,18 +54,9 @@ extensible.
26
54
## Installing
27
55
28
56
``` shell
29
- go get -u github.com/defval/inject/v2
57
+ go get -u github.com/
yoyofxteam/[email protected]
30
58
```
31
59
32
- This library follows [ SemVer] ( http://semver.org/ ) strictly.
33
-
34
- ## Tutorial
35
-
36
- Let's learn to use Inject by example. We will code a simple application
37
- that processes HTTP requests.
38
-
39
- The full tutorial code is available [ here] ( ./_tutorial/main.go )
40
-
41
60
### Providing
42
61
43
62
To start, we will need to create two fundamental types: ` http.Server `
@@ -67,16 +86,20 @@ func NewServeMux() *http.ServeMux {
67
86
Now let's teach a container to build these types.
68
87
69
88
` ` ` go
70
- container := inject.New (
89
+ import (
90
+ di " github.com/yoyofxteam/dependencyinjection"
91
+ )
92
+
93
+ container := di.New (
71
94
// provide http server
72
- inject .Provide (NewServer),
95
+ di .Provide (NewServer),
73
96
// provide http serve mux
74
- inject .Provide (NewServeMux)
97
+ di .Provide (NewServeMux)
75
98
)
76
99
```
77
100
78
- The function ` inject .New()` parse our constructors, compile dependency
79
- graph and return ` *inject .Container ` type for interaction. Container
101
+ The function ` di .New()` parse our constructors, compile dependency
102
+ graph and return ` *di .Container ` type for interaction. Container
80
103
panics if it could not compile.
81
104
82
105
> I think that panic at the initialization of the application and not in
@@ -143,7 +166,7 @@ func NewServer(handler http.Handler) *http.Server {
143
166
```
144
167
145
168
For a container to know that as an implementation of ` http.Handler ` is
146
- necessary to use, we use the option ` inject .As()` . The arguments of this
169
+ necessary to use, we use the option ` di .As()` . The arguments of this
147
170
option must be a pointer(s) to an interface like ` new(Endpoint) ` .
148
171
149
172
> This syntax may seem strange, but I have not found a better way to
@@ -232,11 +255,11 @@ provide option.
232
255
233
256
``` go
234
257
container := inject.New (
235
- inject .Provide (NewServer), // provide http server
236
- inject .Provide (NewServeMux), // provide http serve mux
258
+ di .Provide (NewServer), // provide http server
259
+ di .Provide (NewServeMux), // provide http serve mux
237
260
// endpoints
238
- inject .Provide (NewOrderController, inject .As (new (Controller))), // provide order controller
239
- inject .Provide (NewUserController, inject .As (new (Controller))), // provide user controller
261
+ di .Provide (NewOrderController, di .As (new (Controller))), // provide order controller
262
+ di .Provide (NewUserController, di .As (new (Controller))), // provide user controller
240
263
)
241
264
```
242
265
@@ -276,22 +299,22 @@ type SlaveDatabase struct {
276
299
}
277
300
```
278
301
279
- Second way is a using named definitions with ` inject .WithName()` provide
302
+ Second way is a using named definitions with ` di .WithName()` provide
280
303
option:
281
304
282
305
``` go
283
306
// provide master database
284
- inject .Provide (NewMasterDatabase, inject .WithName (" master" ))
307
+ di .Provide (NewMasterDatabase, di .WithName (" master" ))
285
308
// provide slave database
286
- inject .Provide (NewSlaveDatabase, inject .WithName (" slave" ))
309
+ di .Provide (NewSlaveDatabase, di .WithName (" slave" ))
287
310
```
288
311
289
- If you need to extract it from container use ` inject .Name()` extract
312
+ If you need to extract it from container use ` di .Name()` extract
290
313
option.
291
314
292
315
``` go
293
316
var db *Database
294
- container.Extract (&db, inject .Name (" master" ))
317
+ container.Extract (&db, di .Name (" master" ))
295
318
```
296
319
297
320
If you need to provide named definition in other constructor use
@@ -353,7 +376,7 @@ that transforms to `di.ParameterBag` type.
353
376
354
377
``` go
355
378
// Provide server with parameter bag
356
- inject .Provide (NewServer, inject .ParameterBag {
379
+ di .Provide (NewServer, di .ParameterBag {
357
380
" addr" : " :8080" ,
358
381
})
359
382
@@ -369,10 +392,10 @@ func NewServer(pb di.ParameterBag) *http.Server {
369
392
### Prototypes
370
393
371
394
If you want to create a new instance on each extraction use
372
- ` inject .Prototype()` provide option.
395
+ ` di .Prototype()` provide option.
373
396
374
397
``` go
375
- inject .Provide (NewRequestContext, inject .Prototype ())
398
+ di .Provide (NewRequestContext, di .Prototype ())
376
399
```
377
400
378
401
> todo: real use case
@@ -401,9 +424,9 @@ After `container.Cleanup()` call, it iterate over instances and call
401
424
cleanup function if it exists.
402
425
403
426
``` go
404
- container := inject .New (
427
+ container := di .New (
405
428
// ...
406
- inject .Provide (NewFile),
429
+ di .Provide (NewFile),
407
430
)
408
431
409
432
// do something
@@ -419,7 +442,7 @@ Dependency graph may be presented via
419
442
representation:
420
443
421
444
``` go
422
- var graph *di.Graph
445
+ var graph *di.di . Graph
423
446
if err = container.Extract (&graph); err != nil {
424
447
// handle err
425
448
}
0 commit comments