[Framework] Wire in service compositor

Use service compositor as a form of custom registrar.
Also, add clarifying comments. WTD-518.
This commit is contained in:
Victor Woeltjen
2014-11-05 16:42:15 -08:00
parent 67dac667cf
commit 9e61e89da4
2 changed files with 38 additions and 3 deletions

View File

@ -75,6 +75,12 @@ define(
}]); }]);
} }
// Handle service compositing
function registerComponents(components) {
return new ServiceCompositor(app, $log)
.registerCompositeServices(components);
}
// Utility; create a function which converts another function // Utility; create a function which converts another function
// (which acts on single objects) to one which acts upon arrays. // (which acts on single objects) to one which acts upon arrays.
function mapUpon(func) { function mapUpon(func) {
@ -90,7 +96,8 @@ define(
routes: mapUpon(registerRoute), routes: mapUpon(registerRoute),
directives: mapUpon(new CustomRegistrar("directive")), directives: mapUpon(new CustomRegistrar("directive")),
controllers: mapUpon(new CustomRegistrar("controller")), controllers: mapUpon(new CustomRegistrar("controller")),
services: mapUpon(new CustomRegistrar("service")) services: mapUpon(new CustomRegistrar("service")),
components: registerComponents
}; };
} }

View File

@ -9,6 +9,8 @@ define(
"use strict"; "use strict";
/** /**
* Handles service compositing; that is, building up services
* from provider, aggregator, and decorator components.
* *
* @constructor * @constructor
*/ */
@ -16,6 +18,7 @@ define(
var latest = {}, var latest = {},
providerLists = {}; // Track latest services registered providerLists = {}; // Track latest services registered
// Log a warning; defaults to "no service provided by"
function warn(extension, category, message) { function warn(extension, category, message) {
var msg = message || "No service provided by"; var msg = message || "No service provided by";
$log.warn([ $log.warn([
@ -38,16 +41,21 @@ define(
// Echo arguments; used to represent groups of non-built-in // Echo arguments; used to represent groups of non-built-in
// extensions as a single dependency. // extensions as a single dependency.
function echoSingle() { function echoSingle(value) {
return arguments[0]; return value;
} }
// Generates utility functions to match types (one of
// provider, aggregator, or decorator) of component. Used
// to filter down to specific types, which are handled
// in order.
function hasType(type) { function hasType(type) {
return function (extension) { return function (extension) {
return extension.type === type; return extension.type === type;
}; };
} }
// Make a unique name for a service component.
function makeName(category, service, index) { function makeName(category, service, index) {
return [ return [
service, service,
@ -59,6 +67,8 @@ define(
].join(""); ].join("");
} }
// Register a specific provider instance with Angular, and
// record its name for subsequent stages.
function registerProvider(provider, index) { function registerProvider(provider, index) {
var service = provider.provides, var service = provider.provides,
dependencies = provider.depends || [], dependencies = provider.depends || [],
@ -78,6 +88,9 @@ define(
app.service(name, dependencies.concat([provider])); app.service(name, dependencies.concat([provider]));
} }
// Register an array of providers as a single dependency;
// aggregators will then depend upon this to consume all
// aggregated providers as a single dependency.
function registerProviderSets() { function registerProviderSets() {
Object.keys(providerLists).forEach(function (service) { Object.keys(providerLists).forEach(function (service) {
var name = makeName("provider", service, "*"), var name = makeName("provider", service, "*"),
@ -87,6 +100,9 @@ define(
}); });
} }
// Registers an aggregator via Angular, including both
// its declared dependencies and the additional, implicit
// dependency upon the array of all providers.
function registerAggregator(aggregator, index) { function registerAggregator(aggregator, index) {
var service = aggregator.provides, var service = aggregator.provides,
dependencies = aggregator.depends || [], dependencies = aggregator.depends || [],
@ -113,6 +129,9 @@ define(
app.service(name, dependencies.concat([aggregator])); app.service(name, dependencies.concat([aggregator]));
} }
// Registers a decorator via Angular, including its implicit
// dependency on the latest service component which has come
// before it.
function registerDecorator(decorator, index) { function registerDecorator(decorator, index) {
var service = decorator.provides, var service = decorator.provides,
dependencies = decorator.depends || [], dependencies = decorator.depends || [],
@ -164,6 +183,15 @@ define(
return { return {
/** /**
* Register composite services with Angular. This will build
* up a dependency hierarchy between providers, aggregators,
* and/or decorators, such that a dependency upon the service
* type they expose shall be satisfied by their fully-wired
* whole.
*
* Note that this method assumes that a complete set of
* components shall be provided. Multiple calls to this
* method may not behave as expected.
* *
* @param {Array} components extensions of category component * @param {Array} components extensions of category component
*/ */