1
1
// Obligatory // comment
2
2
3
3
/*
4
-
5
4
Package nject is a general purpose dependency injection framework.
6
5
It provides wrapping, pruning, and indirect variable passing. It is type safe
7
6
and using it requires no type assertions. There are two main injection APIs:
8
7
Run and Bind. Bind is designed to be used at program initialization and
9
8
does as much work as possible then rather than during main execution.
10
9
11
- List of providers
10
+ # List of providers
12
11
13
12
The API for nject is a list of providers (injectors) that are run in order.
14
13
The final function in the list must be called. The other functions are called
@@ -32,7 +31,7 @@ is a simple example:
32
31
In this example, context.Background and log.Default are not invoked because
33
32
their outputs are not used by the final function (http.ListenAndServe).
34
33
35
- How to use
34
+ # How to use
36
35
37
36
The basic idea of nject is to assemble a Collection of providers and then use
38
37
that collection to supply inputs for functions that may use some or all of
81
80
82
81
1st2nd
83
82
84
- Collections
83
+ # Collections
85
84
86
85
Providers are grouped as into linear sequences. When building an injection chain,
87
86
the providers are grouped into several sets: LITERAL, STATIC, RUN. The LITERAL
@@ -100,7 +99,7 @@ The STATIC set is composed of the cacheable injectors.
100
99
101
100
The RUN set if everything else.
102
101
103
- Injectors
102
+ # Injectors
104
103
105
104
All injectors have the following type signature:
106
105
@@ -114,7 +113,7 @@ are dropped from the handler chain. They are not invoked. Injectors
114
113
that have no output values are a special case and they are always retained
115
114
in the handler chain.
116
115
117
- Cached injectors
116
+ # Cached injectors
118
117
119
118
In injector that is annotated as Cacheable() may promoted to the STATIC set.
120
119
An injector that is annotated as MustCache() must be promoted to
@@ -139,7 +138,7 @@ is injected, all chains will share the same pointer.
139
138
return &j
140
139
}))
141
140
142
- Memoized injectors
141
+ # Memoized injectors
143
142
144
143
Injectors in the STATIC set are only run for initialization. For some things,
145
144
like opening a database, that may still be too often. Injectors that are marked
@@ -155,7 +154,7 @@ Memoized injectors may not have any inputs that are go maps, slices, or function
155
154
Arrays, structs, and interfaces are okay. This requirement is recursive so a struct that
156
155
that has a slice in it is not okay.
157
156
158
- Fallible injectors
157
+ # Fallible injectors
159
158
160
159
Fallible injectors are special injectors that change the behavior of the injection
161
160
chain if they return error. Fallible injectors in the RUN set, that return error
@@ -208,7 +207,7 @@ Some examples:
208
207
return nil
209
208
}
210
209
211
- Wrap functions and middleware
210
+ # Wrap functions and middleware
212
211
213
212
A wrap function interrupts the linear sequence of providers. It may or may
214
213
invoke the remainder of the sequence that comes after it. The remainder of
@@ -248,7 +247,11 @@ other kinds of functions: one call to reflect.MakeFunc().
248
247
Wrap functions serve the same role as middleware, but are usually
249
248
easier to write.
250
249
251
- Final functions
250
+ Wrap functions that invoke inner() multiple times in parallel are
251
+ are not well supported at this time and such invocations must have
252
+ the wrap function decorated with Parallel().
253
+
254
+ # Final functions
252
255
253
256
Final functions are simply the last provider in the chain.
254
257
They look like regular Go functions. Their input parameters come
@@ -280,11 +283,11 @@ because they internally control if the downstream chain is called.
280
283
return nil
281
284
}
282
285
283
- Literal values
286
+ # Literal values
284
287
285
288
Literal values are values in the provider chain that are not functions.
286
289
287
- Invalid provider chains
290
+ # Invalid provider chains
288
291
289
292
Provider chains can be invalid for many reasons: inputs of a type not
290
293
provided earlier in the chain; annotations that cannot be honored
@@ -293,7 +296,7 @@ functions that take or return functions with an anymous type other than
293
296
wrapper functions; A chain that does not terminate with a function; etc.
294
297
Bind() and Run() will return error when presented with an invalid provider chain.
295
298
296
- Panics
299
+ # Panics
297
300
298
301
Bind() and Run() will return error rather than panic. After Bind()ing
299
302
an init and invoke function, calling them will not panic unless a provider
@@ -322,7 +325,7 @@ can be added with Shun().
322
325
323
326
var ErrorOfLastResort = nject.Shun(func() error { return nil })
324
327
325
- Chain evaluation
328
+ # Chain evaluation
326
329
327
330
Bind() uses a complex and somewhat expensive O(n^2) set of rules to evaluate
328
331
which providers should be included in a chain and which can be dropped. The goal
@@ -350,14 +353,14 @@ from the closest provider.
350
353
Providers that have unmet dependencies will be eliminated from the chain
351
354
unless they're Required.
352
355
353
- Best practices
356
+ # Best practices
354
357
355
358
The remainder of this document consists of suggestions for how to use nject.
356
359
357
360
Contributions to this section would be welcome. Also links to blogs or other
358
361
discussions of using nject in practice.
359
362
360
- For tests
363
+ # For tests
361
364
362
365
The best practice for using nject inside a large project is to have a few
363
366
common chains that everyone imports.
@@ -398,7 +401,7 @@ to write tests.
398
401
})
399
402
}
400
403
401
- Displaying errors
404
+ # Displaying errors
402
405
403
406
If nject cannot bind or run a chain, it will return error. The returned
404
407
error is generally very good, but it does not contain the full debugging
@@ -417,7 +420,7 @@ Remove the comments to hide the original type names.
417
420
log.Fatal(err)
418
421
}
419
422
420
- Reorder
423
+ # Reorder
421
424
422
425
The Reorder() decorator allows injection chains to be fully or partially reordered.
423
426
Reorder is currently limited to a single pass and does not know which injectors are
@@ -459,7 +462,7 @@ and used.
459
462
OverrideThingOptions(thing.Option1, thing.Option2),
460
463
)
461
464
462
- Self-cleaning
465
+ # Self-cleaning
463
466
464
467
Recommended best practice is to have injectors shutdown the things they themselves start. They
465
468
should do their own cleanup.
@@ -500,7 +503,7 @@ defines. Wrapper functions have a small runtime performance penalty, so if you
500
503
have more than a couple of providers that need cleanup, it makes sense to include
501
504
something like CleaningService.
502
505
503
- Forcing inclusion
506
+ # Forcing inclusion
504
507
505
508
The normal direction of forced inclusion is that an upstream provider is required
506
509
because a downstream provider uses a type produced by the upstream provider.
@@ -514,6 +517,5 @@ produce a type that is only consumed by the downstream provider.
514
517
515
518
Lastly, the providers can be grouped with Cluster so that they'll be included or
516
519
excluded as a group.
517
-
518
520
*/
519
521
package nject
0 commit comments