Dependency Resolvers

Dependency resolvers alters the default way a dependency is created. They are effectively a custom hook that is called to get the dependency being built.

A dependency resolver is simply an object with a resolve(container, resolverKey) method. You can create these and add them to the container. Then when registering an object you tell the container to use the custom resolver to build the object.

Here is an example where rather than registering a class or object to build, a resolverKey is used. The DomResolver resolver will be used to resolve the object.

class DomResolver {
    resolve(container, resolverKey) {
        // return a pretend dom element,
        return {
            get description() {
                return 'Fake DOM element - ' + resolverKey.domId ;
            }
        };
    }
}
let container = new Container();
container.addResolver('domResolver', new DomResolver());
// When using a resolve key to create the registered item we need to add a 'isResolverKey' property. 
// This lets the container know the object you're passing to `register` isn't what should be returned when something calls resolve, 
// rather it'll use this object to create the object in question and return that to the caller. 
container.register('view', { resolver: 'domResolver', domId : 'theDomId', isResolverKey: true });
let view = container.resolve('view');
console.log(view.description);

Output:

Fake DOM element - theDomId

Here is an example where an object injected into a dependency is resolved using a custom resolver.

class DomResolver {
    resolve(container, resolverKey) {
        // return a pretend dom element,
        return {
            get description() {
                return 'Fake DOM element - ' + resolverKey.domId ;
            }
        };
    }
}
let container = new Container();
container.addResolver('domResolver', new DomResolver());
class Controller {
    constructor(view) {
        console.log(view.description);
    }
}
// Note we don't need to specify the 'isResolverKey' property on the resolverKey.
// The container assumes it is as it's being used via `inject`.
container.register('controller', Controller).inject({ resolver: 'domResolver', domId : 'viewId' });
let controller = container.resolve('controller');

Output:

Fake DOM element - viewId

Built in Resolvers

There are 3 built in resolvers.

Delegate

The delegate resolver simply defers object creation to a delegate provided by the resolverKey.

class Foo  {
    constructor(bar) {
        console.log('bar is : [%s]', bar);
    }
}
let container = new Container();
container.register('foo', Foo)
    .inject(
    {
        // Internally the container registers a resolver by key 'delegate'
        resolver: 'delegate',
        // use this function to create the dependency 
        resolve: (container, resolveKey) => {
            return 'barInstance';
        }
    });
let foo = container.resolve('foo');

Output:

bar is : [barInstance]

Injection Factory

The factories discussed under Object Factories are implemented using the built in factory dependency resolver.

External Factory

Under the covers registerFactory uses a built in externalFactory dependency resolver to invoke the factory registered against an identifier.