hypo-container
v1.0.9
Published
A dependency injection container
Downloads
18
Maintainers
Readme
hypo-container
A dependency injection container. Supports NodeJS and browser development.
Install
NPM:
npm install --save hypo-container
Yarn:
yarn add hypo-container
Usage
To create a container create a new instance of the Container
class.
import { Container } from 'hypo-container'
const container = new Container()
A container has two types of dependencies. These are known as services and parameters.
Defining a service
A service is an object that does something as part of a larger system. Examples of services: a database connection, a templating engine, or a mailer. Almost any global object can be a service.
Services are defined using a callback function that returns an instance of an object.
const container = new Container()
container.register('owner', c => {
return new Person('Brian', 26)
})
container.register('cat', c => {
return new Cat('Garfield', 4, c.get('owner'))
})
Alternatively calls to the register()
method can be chained, as demonstrated below.
container
.register('owner', c => new Person('Brian', 26))
.register('cat', c => new Cat('Garfield', 4, c.get('owner')))
Note that the callback has access to the current container's instance, via it's first argument. This allows you to reference other contained services and parameters when defining a new service.
Objects are created only when they are first accessed via the get()
method, so order is not important.
Using a defined service is very easy as demonstrated below.
const cat = container.get('cat')
The above is roughly equivalent to the following.
const cat = new Cat('Garfield', 4, new Person('Brian', 26))
Defining a factory service
By default the same instance of a service is returned when calling the container's get()
method. If you want to return a new instance of the service you can make use of the container's factory()
method as demonstrated below.
container.register('uniqueRobot', container.factory(c => {
return new Robot()
}))
const uniqueRobot = container.get('uniqueRobot')
Defining parameters
Defining a parameter allows for easy configuration of your container from the outside and to store global values.
container.myName = 'Brian'
container.myAge = 26
container.register('me', c => {
return new Person(c.myName, c.myAge)
})
Protecting parameters
To use an anonymous function to define a parameter use the protect()
container method.
container['prop'] = 42
container.register('protected_prop', container.protect(c => {
return c.prop * 2
}))
Update a registered service
In some cases you may want to modify a service definition after it has been defined. You can use the extend()
method to define additional code to be run on your service just after it is created.
container.register('cat', c => {
return new Cat('Garfield', 4, c.get('owner'))
})
container.extend('cat', (storage, c) => {
storage.details = () => `${storage.name} - ${storage.age}`
return storage
})
The first argument is the name of the service to extend, the second a function that gets access to the object instance and the container.
Extend a container
If you use the same libraries over and over, you might want to reuse some services from one project to the next one. You can easily extend a container by registering it to another.
const app = new Container()
app['name'] = 'My Awesome App'
const serviceContainer = new Container()
serviceContainer.register('magicNumberService', c => {
return new MagicNumber()
})
app.register(serviceContainer)
app.get('magicNumberService')
Get the service creation function
When accessing a service, the container automatically calls the function used to supply the service. This creates an instance of that service. If you want to get access to this function, use the raw()
method.
container.register('robot', c => new Robot())
// wraps previously defined robot method to create a factory method
container.register('uniqueRobot', container.factory(c => c.raw('robot')))
Deleting a registered service
You may want to delete a service at some point. To do this you use the delete()
method. Supply the name of a registered service as the first argument in order to delete the service.
container.delete('cat')
Deleting all services
To delete all services call the deleteAll()
method.
container.deleteAll()
Deleting a parameter
As parameters are set directly on the container object they can be deleted using the built in delete
keyword.
container.myNumber = 0987654321
delete container.myNumber
Thanks
Special thanks to the creators and maintainers of Pimple. Hypo attempts to follow the Pimple api for ease of use and familiarity. The Hypo docs also attempt to match that of the Pimple docs.