Object Registration
Note
JavaScript doesn’t have a type system which makes containers a little cumbersome to use. Typically in typed languages you’d utilise information provided by the type system to aid in dependency resolution and injection. However without such a system all is not lost, we can simply use strings (i.e. ‘identifiers’) to identify objects to construct.
You can register an object using one of three methods:
-
container.register(identifier, Item)
.This registers either a constructor function OR an object prototype
Item
using the given stringidentifier
.You can chain calls to alter the registration settings:
let identifier = 'itemKey1'; container .register('identifier', Item) .inject('otherDependencyIdentifier1', 'otherDependencyIdentifier1') .singletonPerContainer() .inGroup('mySimilarObjects');
Here we register
Item
using the stringidentifier
. We state that it requires dependenciesotherDependencyIdentifier1
andotherDependencyIdentifier1
. It’s lifetime management issingletonPerContainer
. It can be resolved using theidentifier
or as part of the groupmySimilarObjects
.In most cases, the argument you pass to
inject()
will be a string identifying another dependency. The container internally calls these ‘dependency keys’. There are more advanced cases where these dependency keys can be objects which reference other code to create the item required for injection. See dependency resolvers; -
container.registerInstance(identifier, objectInstance)
.You can use
registerInstance
to register an existing instance with the given stringidentifier
. -
container.registerFactory(identifier, factory)
.This registers a creation factory using the given string
identifier
. The factory is a function that must return a new object instance. The factory will receive the current container as a first parameter. Any additional arguments passed during theresolve
call will be passed to the factory.container .registerFactory('fooId', (container, ...additionalDependencies) => { let fooDependency = container.resolve('fooDependencyId'); return new Foo(fooDependency, ...additionalDependencies); }) .transient(); let foo = container.resolve('fooId', 1, 2, 3);
Here we register a factory that will resolve a
Foo
. We then resolve an instance (foo
) passing some additional arguments. Our creation factory resolves an additional dependency, then passes this dependency, plus the additional dependencies1, 2, 3
toFoo
s constructor and returns it. It’s registered using a transient scope so each time you resolve it, the factor will be invoked to resolve a newFoo
instance.
Note
We need to manually specify objects dependencies at registration time. This is because there are no means available to inspect arguments required for
constructors
orinit
methods at object instantiation/initialisation time. We specify dependencies viainject