Your SlideShare is downloading. ×
Dependency Injection @ AngularJS
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Dependency Injection @ AngularJS

2,160
views

Published on

Ran Mizrahi from CodeOasis gave a lecture about Angular.js dependency injections, as part of an advanced Angular meetup of the Javascript Israel meetup group. …

Ran Mizrahi from CodeOasis gave a lecture about Angular.js dependency injections, as part of an advanced Angular meetup of the Javascript Israel meetup group.

Ran covered how Dependency Injection works in Angular and its internals, what are providers and the different helper methods angular have for defining injectables components.

Published in: Technology

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
2,160
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
55
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Dependency Injection @ AngularJS Ran Mizrahi (@ranm8) Open Source Dpt. Leader @ CodeOasis Monday, September 9, 13
  • 2. About CodeOasis • CodeOasis specializes in cutting-edge web solutions. • Large variety of customers (from startups to enterprises). • We LOVE JavaScript (-: • Technologies we love: • Symfony2 • AngularJS • nodeJS • HTML5 • CSS3 • Our Microsoft department works with C#, WPF, etc. Monday, September 9, 13
  • 3. What is Dependency Injection??? Monday, September 9, 13
  • 4. The Problem function SessionStore() {} SessionStore.prototype = { set: function(name, value) { window.localStorage.setItem(name, value); }, get: function(name) { return window.localStorage.getItem(name); } } function User() { this.sessionStore = new SessionStore(); } User.prototype = { setSession: function(session) { this.sessionStore.set('session', session); }, getSession: function() { return this.sessionStore.get('session'); } } Monday, September 9, 13
  • 5. The Problem Everything goes well and the code is working. But now we have to change the session name... We can use a global variable: sessionName = 'newSessionName'; function User() { this.sessionStore = new SessionStore(); } // ... Maybe we should hard-coded pass it to the store: function User() { this.sessionStore = new SessionStore('newSessionName'); } // ... Monday, September 9, 13
  • 6. The Problem How would you change the entire SessionStore implementation? Cookies Server ... function User() { this.sessionStore = registry.get('SessionStore'); } // ... Should we use some global registry object?? How would we test the User?? Monday, September 9, 13
  • 7. The Problem All those solutions are bad because: • Couples code to one implementation. • Hard to configure • Cannot change the implementation without changing the User prototype. • Untestable code unless you monkey patch it. Monday, September 9, 13
  • 8. Dependency Injection Dependency injection is a software design pattern that allows the removal of hard-coded dependencies and makes it possible to change them. -- Wikipedia Monday, September 9, 13
  • 9. Dependency Injection To The Rescue! Instead of instantiating the SessionStore within the User... function User(sessionStore) { this.sessionStore = sessionStore; } // ... var user = new User(new SessionStore()); JUST INJECT IT!!! Monday, September 9, 13
  • 10. Advantages Of Using DI Use different session store strategies... function User(sessionStore) { this.sessionStore = sessionStore; } // ... var user = new User(new CookieSessionStore()); Monday, September 9, 13
  • 11. Advantages Of Using DI Configuration becomes easy... function User(sessionStore) { this.sessionStore = sessionStore; } // ... var user = new User(new SessionStore('mySessionName')); Monday, September 9, 13
  • 12. Advantages Of Using DI Now we can easily mock the SessionStore (for testing purposes)... function User(sessionStore) { this.sessionStore = sessionStore; } // ... var user = new User(new MockSessionStore()); Monday, September 9, 13
  • 13. All those things makes our code MAINTAINABLE because we’ve.. Less code Extensible Testable Monday, September 9, 13
  • 14. But How To Scale It?!!?!? But what if we have a slightly more complex application.. And we do that in many different places around our application: var user = new User(new SessionStore(new SomeThirdParty(jQuery), new Http(new Thing())), new Something()); //.... var user = new User(new SessionStore(new SomeThirdParty(jQuery), new Http(new Thing())), new Something()); //.... var user = new User(new SessionStore(new SomeThirdParty(jQuery), new Http(new Thing())), new Something()); Monday, September 9, 13
  • 15. Don’t worry! Monday, September 9, 13
  • 16. DI Container To The Rescue Monday, September 9, 13
  • 17. DI Container (e.g. Injector, Provider) • Instantiates objects and their dependencies on demand. • Allows to configure objects before instantiation. • Can instantiate new objects on demand or provide existing ones from cache. • The objects must never know they are being managed by the container. • A container should be able to manage any object. Monday, September 9, 13
  • 18. AngularJS DI Monday, September 9, 13
  • 19. How The DI Injector Works?! • Angular inject the requested service by the function argument names. • Can also be done with an array. • Once requested Angular’s injector would instantiate the requested service and inject it. angular.module('myModule') .controller('MyCtrl', MyCtrl); function MyCtrl($http) { $http.get('http://google.com').then(getTheMonkey); } Monday, September 9, 13
  • 20. The Array Notation • Allows minifiers to preserve argument names for the dependency injection to work with. • More flexible - Separates dependency declaration from your unit. angular.module('myModule') .controller('MyCtrl', ['$http', MyCtrl]); function MyCtrl($http) { $http.get('http://google.com').then(getTheMonkey); } Monday, September 9, 13
  • 21. Changing The Implementation angular.module('myModule') .controller('MyCtrl', ['myHttp', MyCtrl]) .factory('myHttp', ['$q', myHttp]); function myHttp($q) { return { get: function() { var defer = $q.defer(); // Do something with XHR and return a promise... return defer.promise; } }; } function MyCtrl($http) { $http.get('http://google.com').then(someCallback); } • Changes the implementation by changing only the array notation. • Angular’s injector instantiates the dependencies of each dependency. Monday, September 9, 13
  • 22. How Do I Use It? Monday, September 9, 13
  • 23. Service/Factory A service is the Angular way of exposing objects within the $injector. • Can have multiple dependencies that will be injected when invoked. angular.module('myModule') .service('myHttp', ['$q', myHttp]); function myHttp($q) { this.get = function() { var defer = $q.defer(); // Do something with XHR and return a promise... return defer.promise; }; } Monday, September 9, 13
  • 24. Factory Shorthand for registering services without a constructor function (assigned to $get property directly). angular.module('myModule') .factory('myHttp', ['$q', myHttp]); function myHttp($q) { return { get: function() { var defer = $q.defer(); // Do something with XHR and return a promise... return defer.promise; } }; } Monday, September 9, 13
  • 25. Provider Registers a provider to a service. • Allows the save configuration state to the service. • Only constants can be injected. • The provider is a constructor function. • $get is a function that returns the actual service. Monday, September 9, 13
  • 26. Provider angular.module('myModule') .provider('myHttp', myHttp); function myHttp() { var baseUrl; this.baseUrl = function(value) { if (!value) { return baseUrl; } baseUrl = value; }; this.$get = ['$q', function() { // myHttp service implementation... }]; } Monday, September 9, 13
  • 27. Configuration Phase vs. Run Phase Configuration Phase Run Phase • Runs before any service was instantiated. • Only providers can be injected. • Each provider is injected with the “Provider” suffix (e.g. $locationProvider) • Allows to purely configure the services state. • Services state should be not be changed now (already configured during run phase). • Providers now cannot be injected. Monday, September 9, 13
  • 28. Config Use the service providers to configure the services state during the config phase to the run phase. angular.module('myModule') .config(['myHttpProvider', '$locationProvider', appConfig]); function appConfig(myHttpProvider, $locationProvider) { // Configure app to use HTML5 History API.. $locationProvider.html5Mode(true); // Configure my service baseUrl.. myHttpProvider.baseUrl('http://www.example.com'); } Monday, September 9, 13
  • 29. Value Value is a shorthand to register a simple value as a service. angular.module('myModule') .value('myHttp', 'some string'); Monday, September 9, 13
  • 30. Constant Constant is the same as value, but unlike value it can be injected to configuration function angular.module('myModule') .constant('someConstant', '123'); Monday, September 9, 13
  • 31. Angular’s DI In Testing describe('myHttp', function() { var mockQ = { then: function(){} }, http; beforeEach(module(function($provide) { $provide.value('$q', mockQ); })); beforeEach(inject(function(myHttp) { http = myHttp; })); describe('#get()', function() { it('should return a promise', function() { // test your code here }); }); }); Monday, September 9, 13
  • 32. Questions? Thank you! Monday, September 9, 13