AngularJS Learn Part 2 AngularJS Dependency Injection

  • 2021-07-21 05:39:59
  • OfStack

Introduction:

First of all, we need to understand what dependency injection is.
What is the difference between inversion of control and dependency injection?
Assumption: The application A needs to access the external resource C. Container B (a framework program used to implement IOC/DI functions) is used here.
A requires access to C
B gets C and returns it to A
IOC inversion of control inversion of control: Stand at container angle. B controls A, and B injects C into A in reverse. That is, the container controls the application, and the container injects the external resources needed by the application into the application in reverse.
DI Dependency Injection Dependency Injection: From an application perspective. A relies on B to obtain C, and B injects C into A. That is, the application relies on the container to create and inject the external resources it needs.

AngularJS Dependency Injection

Provider Service ($provide)

AngularJS provides a good dependency injection mechanism. The following five core components are used as dependency injection:

value
factory
service
provider
constant
decorator (soy sauce)

Constant

For defining constants, the value of this definition cannot be changed, of course, it can be injected anywhere, but it cannot be decorated by the decorator (decorator)


var app = angular.module('app', []);
app.config(function ($provide) {
 $provide.constant('movieTitle', 'The Matrix');
});
app.controller('ctrl', function (movieTitle) {
 expect(movieTitle).toEqual('The Matrix');
});
//  Grammar sugar: 
app.constant('movieTitle', 'The Matrix');

Value

This product can be string, number or even function, which differs from constant in that it can be modified and not injected into config, but it can be decorated with decorator


var app = angular.module('app', []);
app.config(function ($provide) {
 $provide.value('movieTitle', 'The Matrix')
});
app.controller('ctrl', function (movieTitle) {
 expect(movieTitle).toEqual('The Matrix');
});
//  Grammar sugar: 
app.value('movieTitle', 'The Matrix');

Service

It is an injectable constructor, which is singleton in AngularJS, and is suitable for communicating or sharing data in Controller.


var app = angular.module('app' ,[]);
app.config(function ($provide) {
 $provide.service('movie', function () {
  this.title = 'The Matrix';
 });
});
app.controller('ctrl', function (movie) {
 expect(movie.title).toEqual('The Matrix');
});
//  Grammar sugar: 
app.service('movie', function () {
 this.title = 'The Matrix';
});

Factory

It is an injectable function. The difference between factory and service is that factory is an ordinary function, while service is a constructor (constructor), so Angular will use new keyword when calling service, while calling factory only calls ordinary function, so factory can return anything, while service can not return (see the role of new keyword).


var app = angular.module('app', []);
app.config(function ($provide) {
 $provide.factory('movie', function () {
  return {
   title: 'The Matrix';
  }
 });
}); 
app.controller('ctrl', function (movie) {
 expect(movie.title).toEqual('The Matrix');
});
//  Grammatical sugar 
app.factory('movie', function () {
 return {
  title: 'The Matrix';
 }
});

Provider

provider is their boss. Almost all of the above (except constant) are encapsulations of provider. provider must have a $get method. Of course, provider can also be said to be a configurable factory.


var app = angular.module('app', []);
app.provider('movie', function () {
 var version;
 return {
  setVersion: function (value) {
   version = value;
  },
  $get: function () {
   return {
     title: 'The Matrix' + ' ' + version
   }
  }
 }
});
app.config(function (movieProvider) {
 movieProvider.setVersion('Reloaded');
});
app.controller('ctrl', function (movie) {
 expect(movie.title).toEqual('The Matrix Reloaded');
});

Decorator

This one is special, it's not provider, it's used to decorate other provider, and as I said earlier, it can't decorate Constant, because Constant was not actually created by provider () method.


var app = angular.module('app', []);
app.value('movieTitle', 'The Matrix');
app.config(function ($provide) {
 $provide.decorator('movieTitle', function ($delegate) {
  return $delegate + ' - starring Keanu Reeves';
 });
});
app.controller('myController', function (movieTitle) {
 expect(movieTitle).toEqual('The Matrix - starring Keanu Reeves');
});

Summary:

All vendors are instantiated only once, which means they are singletons
All suppliers except constant can be decorated with decorators (decorator)
value is a simple injectable value
service is an injectable constructor
factory is an injectable method
decorator can modify or encapsulate other vendors except, of course, constant
provider is a configurable factory

Above sources: (Provider in AngularJS: the difference between Service and Factory, etc.) https://segmentfault.com/a/1190000003096933

Injector ($injector)

The injector is responsible for creating injected instances from the services we created through provide. As long as you write a parameter with injectability, you can see how the injector works. Every AngularJS application has only 11 injector, which is created when the application starts, and you can get it by injecting injector into any injectable function ($injector knows how to inject itself!) .
1 Once you have injector, you can call the get function to get an instance of any service that has been defined.


var movie = $injector.get('movie');
expect(movie.title).toEqual('The Matrix Reloaded');

The injector is also responsible for injecting services into functions; For example, you can magically inject a service into any function, as long as you use the injector's invoke method:


var myFunction = function(movie) {
 return movie.title;
};
$injector.invoke(myFunction);

If the injector only creates an instance of a service once, then it is not a big deal. The great thing about it is that it can cache anything returned from an provider through the service name, and the next time you use this service again, you will get the same object.
Therefore, it makes sense that you can inject services into any function by calling injector. invike. Including:

Controller definition function Instruction definition function Filter definition function The $get method in provider (that is, the factory function)

Since constant and value always return a static value, they are not called through the injector, so you cannot inject anything into them.


Related articles: