KEMBAR78
ngMess: AngularJS Dependency Injection | PDF
ngMess: 
Angular JS DI
Presenter 
Dmitry Ivashutin 
Software Engineer
Dependency Injection 
High-level modules should not depend on 
low-level modules. Both should depend 
on abstractions. 
 Abstractions should not depend on details. 
Details should depend on abstractions.
DI in a Nutshell 
 create the dependency 
 look up the dependency 
 have the dependency injected
The provider
Wiki: The provider 
The $provide service is responsible for telling Angular how 
to create new injectable things; these things are 
called services. Services are defined by things 
called providers, which is what you're creating when you 
use $provide. Defining a provider is done via 
the provider method on the $provide service, and you can 
get hold of the $provide service by asking for it to be injected 
into an application's config function. 
https://github.com/angular/angular.js/wiki/Understanding-Dependency-Injection
How do we usually inject? 
myApp.service('alerter', function () { 
http://jsfiddle.net/ae87/9x7Aq/2/ 
this.sayHello = function(){ 
alert('Hello! '); 
} 
this.sayGoodbye = function(){ 
alert('Goodbye!'); 
} 
});
Let’s start from
Create provider at configure stage 
app.config(function ($provide) { 
$provide.provider('greeting', function () { 
this.$get = function () { 
return function (name) { 
alert('Hello, ' + name); 
}; 
}; 
}); 
});
It’s a valid way
There are other ways
So called “services” 
Factory Service 
Provider 
Value Constant
Calling exact the same code inside 
that we wrote above
Provider way 
function provider(name, provider_) { 
assertNotHasOwnProperty(name, 'service'); 
if (isFunction(provider_) || isArray(provider_)) { 
provider_ 
= providerInjector.instantiate(provider_); 
} 
if (!provider_.$get) 
return providerCache[name + providerSuffix] 
= provider_; 
}
Factory way 
function factory(name, factoryFn) { 
return provider( 
name, 
{ 
$get: factoryFn 
}); 
}
Service way 
function service(name, constructor) { 
return factory( 
name, 
[ 
'$injector', 
function ($injector) { 
return $injector.instantiate(constructor); 
} 
]); 
}
Value way 
function value(name, val) { 
return factory( 
name, 
valueFn(val) 
); 
} 
function valueFn(value) { 
return function () { 
return value; 
}; 
}
Constant way 
function constant(name, value) { 
assertNotHasOwnProperty(name, 'constant'); 
providerCache[name] = value; 
instanceCache[name] = value; 
}
Syntactic sugar
Looks annoying, right? 
app.config(function($provide) { ... })
Module level access 
$provide 
.provider('greeting', ...); 
angular 
.module('myModule', []) 
.provider('greeting', ...);
“A Sound of Thunder”
Service Recipe 
 Utility functions via public API 
 Non-new-able stuff 
Works better for objects of custom type 
service(class) 
– registers a constructor function, 
class that will be wrapped in 
a service provider object
Factory Recipe 
 Exposing public API 
 Constructors via new-able functions 
Can produce JavaScript primitives and functions 
factory(fn) 
– registers a service factory 
function, that will be wrapped 
in a service provider object
Provider Recipe 
 Configurable stuff 
You don't need it unless you are building a 
reusable piece of code that needs global 
configuration 
provider(provider) 
– registers a service provider 
with the $injector
Value Recipe 
 Exposing static values and constants 
value(obj) 
– registers a value/object that 
can only be accessed by 
services, not providers
Constant Recipe 
 Exposing compile time static values and 
constants 
constant(obj) 
– registers a value/object 
that can be accessed by 
providers and services
Decorator
Decorator way 
function decorator(serviceName, decorFn) { 
var origProvider = providerInjector 
.get(serviceName + providerSuffix), 
orig$get = origProvider.$get; 
origProvider.$get = function () { 
var origInstance = instanceInjector 
.invoke(orig$get, origProvider); 
return instanceInjector.invoke( 
decorFn, null, 
{ $delegate: origInstance }); 
}; 
}
Know-how 
app.config(function ($provide) { 
$provide.decorator('$log', function ($delegate) { 
// save the original function 
var _log = $delegate.log; 
// replace the original behavior 
$delegate.log = function (msg) { 
_log(msg); 
alert(msg); 
}; 
return $delegate; 
}); 
}); 
http://plnkr.co/edit/imqmvUfk4oWWuwg75sP1?p=preview
Few more quick facts
Injector: Why 
 Feel the power of DI 
 Control the injection real-time 
 Access DI container from outside of your app 
 Primary usage - testing
Injector: How 
function MyController($scope, $injector) { 
$scope.doSomething = function(someServiceName) { 
// someService contains the name of a service 
var service = $injector.get(someServiceName); 
service.do(); 
}; 
}
Scripts require proper order
The End! Questions?

ngMess: AngularJS Dependency Injection

  • 1.
  • 2.
    Presenter Dmitry Ivashutin Software Engineer
  • 3.
    Dependency Injection High-levelmodules should not depend on low-level modules. Both should depend on abstractions.  Abstractions should not depend on details. Details should depend on abstractions.
  • 4.
    DI in aNutshell  create the dependency  look up the dependency  have the dependency injected
  • 5.
  • 6.
    Wiki: The provider The $provide service is responsible for telling Angular how to create new injectable things; these things are called services. Services are defined by things called providers, which is what you're creating when you use $provide. Defining a provider is done via the provider method on the $provide service, and you can get hold of the $provide service by asking for it to be injected into an application's config function. https://github.com/angular/angular.js/wiki/Understanding-Dependency-Injection
  • 8.
    How do weusually inject? myApp.service('alerter', function () { http://jsfiddle.net/ae87/9x7Aq/2/ this.sayHello = function(){ alert('Hello! '); } this.sayGoodbye = function(){ alert('Goodbye!'); } });
  • 9.
  • 10.
    Create provider atconfigure stage app.config(function ($provide) { $provide.provider('greeting', function () { this.$get = function () { return function (name) { alert('Hello, ' + name); }; }; }); });
  • 11.
  • 13.
  • 14.
    So called “services” Factory Service Provider Value Constant
  • 15.
    Calling exact thesame code inside that we wrote above
  • 16.
    Provider way functionprovider(name, provider_) { assertNotHasOwnProperty(name, 'service'); if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } if (!provider_.$get) return providerCache[name + providerSuffix] = provider_; }
  • 17.
    Factory way functionfactory(name, factoryFn) { return provider( name, { $get: factoryFn }); }
  • 18.
    Service way functionservice(name, constructor) { return factory( name, [ '$injector', function ($injector) { return $injector.instantiate(constructor); } ]); }
  • 19.
    Value way functionvalue(name, val) { return factory( name, valueFn(val) ); } function valueFn(value) { return function () { return value; }; }
  • 20.
    Constant way functionconstant(name, value) { assertNotHasOwnProperty(name, 'constant'); providerCache[name] = value; instanceCache[name] = value; }
  • 22.
  • 23.
    Looks annoying, right? app.config(function($provide) { ... })
  • 24.
    Module level access $provide .provider('greeting', ...); angular .module('myModule', []) .provider('greeting', ...);
  • 25.
    “A Sound ofThunder”
  • 27.
    Service Recipe Utility functions via public API  Non-new-able stuff Works better for objects of custom type service(class) – registers a constructor function, class that will be wrapped in a service provider object
  • 28.
    Factory Recipe Exposing public API  Constructors via new-able functions Can produce JavaScript primitives and functions factory(fn) – registers a service factory function, that will be wrapped in a service provider object
  • 29.
    Provider Recipe Configurable stuff You don't need it unless you are building a reusable piece of code that needs global configuration provider(provider) – registers a service provider with the $injector
  • 30.
    Value Recipe Exposing static values and constants value(obj) – registers a value/object that can only be accessed by services, not providers
  • 31.
    Constant Recipe Exposing compile time static values and constants constant(obj) – registers a value/object that can be accessed by providers and services
  • 32.
  • 33.
    Decorator way functiondecorator(serviceName, decorFn) { var origProvider = providerInjector .get(serviceName + providerSuffix), orig$get = origProvider.$get; origProvider.$get = function () { var origInstance = instanceInjector .invoke(orig$get, origProvider); return instanceInjector.invoke( decorFn, null, { $delegate: origInstance }); }; }
  • 34.
    Know-how app.config(function ($provide){ $provide.decorator('$log', function ($delegate) { // save the original function var _log = $delegate.log; // replace the original behavior $delegate.log = function (msg) { _log(msg); alert(msg); }; return $delegate; }); }); http://plnkr.co/edit/imqmvUfk4oWWuwg75sP1?p=preview
  • 36.
  • 37.
    Injector: Why Feel the power of DI  Control the injection real-time  Access DI container from outside of your app  Primary usage - testing
  • 38.
    Injector: How functionMyController($scope, $injector) { $scope.doSomething = function(someServiceName) { // someService contains the name of a service var service = $injector.get(someServiceName); service.do(); }; }
  • 39.
  • 40.