Unverified Commit 2e287c68 authored by Robert Knight's avatar Robert Knight Committed by GitHub

Merge pull request #2011 from hypothesis/replace-angular-run

Use `Injector` to initialize services
parents 6e0e57d3 4d210869
...@@ -34,7 +34,11 @@ function isValidProvider(provider) { ...@@ -34,7 +34,11 @@ function isValidProvider(provider) {
* *
* To construct an object, call the `register` method with the name and provider * To construct an object, call the `register` method with the name and provider
* for the object and each of its dependencies, and then call * for the object and each of its dependencies, and then call
* the `get` method to construct the object and its dependencies return it. * the `get` method to construct the object and its dependencies and return it.
*
* To run a function with arguments provided by the container, without registering
* the function in the container for use by other factories or classes,
* use the `run` method.
*/ */
export class Injector { export class Injector {
constructor() { constructor() {
...@@ -134,4 +138,25 @@ export class Injector { ...@@ -134,4 +138,25 @@ export class Injector {
this._providers.set(name, provider); this._providers.set(name, provider);
return this; return this;
} }
/**
* Run a function which uses one or more dependencies provided by the
* container.
*
* @param {Function} -
* A callback to run, with dependencies annotated in the same way as
* functions or classes passed to `register`.
* @return {any} - Returns the result of running the function.
*/
run(callback) {
const tempName = 'Injector.run';
this.register(tempName, { factory: callback });
try {
return this.get(tempName);
} finally {
this._instances.delete(tempName);
this._providers.delete(tempName);
}
}
} }
...@@ -153,4 +153,52 @@ describe('Injector', () => { ...@@ -153,4 +153,52 @@ describe('Injector', () => {
}); });
}); });
}); });
describe('#run', () => {
const FIRST_VALUE = 3;
const SECOND_VALUE = 5;
function createContainer() {
const container = new Injector();
container
.register('first', { value: FIRST_VALUE })
.register('second', { value: SECOND_VALUE });
return container;
}
it('calls function with resolved dependencies as arguments', () => {
const stub = sinon.stub();
stub.$inject = ['first', 'first', 'second'];
const container = createContainer();
container.run(stub);
assert.calledWith(stub, FIRST_VALUE, FIRST_VALUE, SECOND_VALUE);
});
it("returns the function's result", () => {
function add(first, second) {
return first + second;
}
add.$inject = ['first', 'second'];
const container = createContainer();
const result = container.run(add);
assert.equal(result, FIRST_VALUE + SECOND_VALUE);
});
it('can be called multiple times', () => {
const container = createContainer();
let total = 0;
function increment(first) {
total += first;
}
container.run(increment);
container.run(increment);
assert.equal(total, FIRST_VALUE * 2);
});
});
}); });
...@@ -231,6 +231,18 @@ function startAngularApp(config) { ...@@ -231,6 +231,18 @@ function startAngularApp(config) {
.register('$rootScope', { value: $rootScope }); .register('$rootScope', { value: $rootScope });
} }
// Run initialization logic that uses constructed services.
//
// @ngInject
function initServices() {
container.run(persistDefaults);
container.run(autosave);
container.run(sendPageView);
container.run(setupApi);
container.run(setupRoute);
container.run(startRPCServer);
}
const wrapComponent = component => wrapReactComponent(component, container); const wrapComponent = component => wrapReactComponent(component, container);
angular angular
...@@ -262,10 +274,7 @@ function startAngularApp(config) { ...@@ -262,10 +274,7 @@ function startAngularApp(config) {
// Register services, the store and utilities with Angular, so that // Register services, the store and utilities with Angular, so that
// Angular components can use them. // Angular components can use them.
.service('analytics', () => container.get('analytics')) .service('analytics', () => container.get('analytics'))
.service('annotationsService', () => container.get('annotationsService'))
.service('api', () => container.get('api'))
.service('auth', () => container.get('auth')) .service('auth', () => container.get('auth'))
.service('autosaveService', () => container.get('autosaveService'))
.service('bridge', () => container.get('bridge')) .service('bridge', () => container.get('bridge'))
.service('features', () => container.get('features')) .service('features', () => container.get('features'))
.service('flash', () => container.get('flash')) .service('flash', () => container.get('flash'))
...@@ -274,16 +283,12 @@ function startAngularApp(config) { ...@@ -274,16 +283,12 @@ function startAngularApp(config) {
.service('loadAnnotationsService', () => .service('loadAnnotationsService', () =>
container.get('loadAnnotationsService') container.get('loadAnnotationsService')
) )
.service('persistedDefaults', () => container.get('persistedDefaults'))
.service('rootThread', () => container.get('rootThread')) .service('rootThread', () => container.get('rootThread'))
.service('router', () => container.get('router'))
.service('searchFilter', () => container.get('searchFilter')) .service('searchFilter', () => container.get('searchFilter'))
.service('serviceUrl', () => container.get('serviceUrl')) .service('serviceUrl', () => container.get('serviceUrl'))
.service('session', () => container.get('session')) .service('session', () => container.get('session'))
.service('streamer', () => container.get('streamer')) .service('streamer', () => container.get('streamer'))
.service('streamFilter', () => container.get('streamFilter')) .service('streamFilter', () => container.get('streamFilter'))
.service('threadsService', () => container.get('threadsService'))
.service('toastMessenger', () => container.get('toastMessenger'))
// Redux store // Redux store
.service('store', () => container.get('store')) .service('store', () => container.get('store'))
...@@ -296,13 +301,7 @@ function startAngularApp(config) { ...@@ -296,13 +301,7 @@ function startAngularApp(config) {
// Make Angular built-ins available to services constructed by `container`. // Make Angular built-ins available to services constructed by `container`.
.run(registerAngularServices) .run(registerAngularServices)
.run(initServices);
.run(persistDefaults)
.run(autosave)
.run(sendPageView)
.run(setupApi)
.run(setupRoute)
.run(startRPCServer);
// Work around a check in Angular's $sniffer service that causes it to // Work around a check in Angular's $sniffer service that causes it to
// incorrectly determine that Firefox extensions are Chrome Packaged Apps which // incorrectly determine that Firefox extensions are Chrome Packaged Apps which
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment