@sapphirejs/container
v0.0.15
Published
IOC Container for Sapphire Framework
Downloads
8
Readme
IOC Container
An IOC (Inversion of Control) container used internally in Sapphire Framework to register and resolve practically every service. A container is a great idea when your services need boostrapping, such as configuration or dependency injection. By registering them in the container is not only convenient, but makes them very easy to swap with a different implementation.
Installation
$ npm install --save @sapphirejs/container
Registering Services
You can register a service using the register
method and passing a callback where you initialize that service. That callback may be a simple function or, more probably, a class instance. In the example below imagine you have a Mail
class that you need to register in the container:
class Mail {
constructor(smtp) {
// Imaginary connect() method.
this.connection = connect(smtp)
}
send(to) {
return this.connection.send(to)
}
}
module.exports = Mail
Service registration should happen in a dedicated place, like a MailServiceProvider
, but we're keeping it simple and ignoring that fact. We'll simply register it somewhere in our app:
const Container = require('@sapphirejs/container')
const Mail = require('./Mail')
const container = new Container()
container.register(Mail, () => {
return new Mail({ server: 'smtp.example.com' })
})
The Mail
class is now registered by passing the class as the identifier. You could simply use "mail" or any other name, it wouldn't make much of a difference. Using a class name makes it less error prone though.
Singleton Services
In exactly the same way as a normal service, you can register singletons. The main difference is that when resolving, the container will use the same instance again and again. This is useful when you need an object to keep its state during the lifecycle of an application, such as reading configuration or other expensive operations. In the example of the Mail
class, it would be a perfect match for a singleton, as we need to connect to the SMTP server only once and keep the connection alive.
const Container = require('@sapphirejs/container')
const Mail = require('./Mail')
const container = new Container()
container.singleton(Mail, () => {
return new Mail({ server: 'smtp.example.com' })
})
Resolving Services
Registered services need to be resolved, and that's exactly what the resolve
method does. It checks the pool of services and either returns a new instance, or an existing one in case of a singleton.
const Container = require('@sapphirejs/container')
const Mail = require('./Mail')
const container = new Container()
const mail = container.resolve(Mail)
mail.send('[email protected]')
As previously said, the identifier of the service can be anything. If it's too much of a hassle requiring the original module everytime you need to resolve it, you can always use a string:
const Container = require('@sapphirejs/container')
const Mail = require('./Mail')
const container = new Container()
container.register("mail", () => {
return new Mail({ server: 'smtp.example.com' })
})
// somewhere else in the application
const mail = container.resolve("mail")
mail.send('[email protected]')