UNPKG

2.07 kBMarkdownView Raw
1# Dependency injection
2
3We have built our own super simple DI.
4
5## Install
6
7`npm install @mindhive/di`
8
9## Motivations and benefits
10
11- Prefer pure functions
12- Avoid ES6 imports as they are difficult to test
13- Especially avoid Meteor package imports as most test runners don't understand Meteor's packaging
14 (they can be accessed through Meteor globals but that's not a great idea either)
15
16## Lifecycle
17
181. Main file for the app should import all of it's modules using `initModules()`
19
202. Modules should export a default function
21
22 - For example: `export default () => { ...; return { serviceName: new Service(), ... } }`
23 - Return an object where the keys map service names to the service objects/functions to be
24 put into the app context
25 - Modules further down thru the array passed to `initModules()` can use services added to the
26 appContext by earlier modules. The module function is passed the current appContext
27 (destructing works a treat), for example:
28 `export default ({ Meteor, Mongo }) => { ... }`
29 - Modules don't have to return anything, you can use them to perform other initialization
30 - Modules are called inside `Meteor.startup` so there is no need to manage that yourself
31
323. To access services in the appContext call `app()` to get the appContext
33
34## Testing
35
36In the example below `service` will be the only object in the appContext and available to any
37code that calls `app()`.
38
39```javascript
40import { mockAppContext } from '@mindhive/di'
41const modules = () => ({
42 service: { foo: sinon.spy() }
43})
44it('should call service.foo()',
45 mockAppContext(modules, () => {
46 funcUnderTest()
47 service.foo.should.have.been.calledOnce
48 })
49)
50````
51
52`modules` is a function so that the spys and dummy values used in it
53are recreated every test, avoiding any contamination to the next test.
54
55However, if your test runner doesn't teardown the tests properly it
56may be necessary to use `resetAppContext`.
57
58You can also use `initModules` within the 'modules' function, it operates
59exactly as it would in production code.
60
\No newline at end of file