Mastering Web Application

(Rick Simeone) #1
Chapter 1

The preceding code is tightly coupled to one implementation of an archive
(NotificationsArchive), since this particular implementation is instantiated
using the new keyword. This is unfortunate since the only contract to which both
classes need to adhere to is the archive method (accepting a notification message
to be archived).


The ability to swap collaborators is extremely important for testability. It is
hard to imagine testing objects in isolation without the ability to substitute real
implementations with fake doubles (mocks). On the following pages of this chapter,
we are going to see how to refactor this tightly-coupled cluster of objects into a
flexible and testable set of services working together. In the process of doing so, we
are going to take full advantage of the AngularJS dependency injection subsystem.


Registering services

AngularJS is only capable of wiring up objects it is aware of. As a consequence, the
very first step for plugging into DI machinery is to register an object with an AngularJS
module. We are not registering the object's instance directly, rather we are throwing
object-creation recipes into the AngularJS dependency injection system. AngularJS
then interprets those recipes to instantiate objects, and then connects them accordingly.
The end effect is a set of instantiated, wired-up objects forming a running application.


In AngularJS there is a dedicated $provide service that allows us to register different
recipes for objects creation. Registered recipes are then interpreted by the $injector
service to provide fully-baked, ready-to-be-used object instances (with all the
dependencies resolved and injected).


Objects that were created by the $injector service are referred to as services.
AngularJS will interpret a given recipe only once during the application's lifecycle,
and as a result will create only a single instance of an object.


Services created by $injector are singletons. There will be only one or
instance of a given service per instance of a running application.

At the end of the day, AngularJS module just holds a set of object instances but we
can control how those objects are created.


Values


The easiest way of having AngularJS to manage an object is to register a pre-
instantiated one as follows:


var myMod = angular.module('myMod', []);
myMod.value('notificationsArchive', new NotificationsArchive());
Free download pdf