Using services
Basic usage
To use a service in Diabolo, you need to use the createFunction
function.
import * as DI from 'diabolo'
const mainFunction = DI.createFunction(function* () {
// ...
})
Note
The createFunction
function does nothing other than returning what
you pass to it. It is used to improve your development experience,
but you can use the function*
syntax directly if you want.
Now, you can use the yield * DI.requireService
function to get the
service you want.
import * as DI from 'diabolo'
const mainFunction = DI.createFunction(function* () {
const myService = yield * DI.requireService(myService)
myService.myFunction()
})
Your function can also be asynchronous.
import * as DI from 'diabolo'
const mainFunction = DI.createFunction(async function* () {
const myService = yield * DI.requireService(myService)
await myService.myFunction()
})
Composing functions
You can run a function inside another function by using the yield *
syntax.
import * as DI from 'diabolo'
const function1 = DI.createFunction(function* () {
const myService = yield * DI.requireService(myService)
myService.myFunction()
})
const function2 = DI.createFunction(function* () {
yield * function1()
})
Stateful services
When you use the requireService
function, it will run the lazy implementation
of the service if it has not been run yet. Otherwise, if you already required
the service, it will return the same instance.
In other words, by default, services have a state.
It means that you can access and modify the same state in different functions.
import * as DI from 'diabolo'
interface CounterService extends DI.Service<'Counter', {
increment: () => void
state: number
}> { }
const counterService = DI.createService<CounterService>('Counter')
const counterServiceImpl = DI.lazyCreateServiceImpl<CounterService>(() => {
let state = 0
return {
increment: () => {
state++
},
get state() { return state },
}
})
const function1 = DI.createFunction(function* () {
const counter = yield * DI.requireService(counterService)
counter.increment()
})
const function2 = DI.createFunction(function* () {
const counter = yield * DI.requireService(counterService)
counter.increment()
})
const function3 = DI.createFunction(function* () {
const counter = yield * DI.requireService(counterService)
return counter.state
})
const mainFunction = DI.createFunction(function* () {
yield * function1()
yield * function2()
const state = yield * function3()
return state
})
const result = DI.provide(mainFunction, {
Counter: counterServiceImpl
})()
// result === 2