With AngularJS's popularity, dependency injection has attracted a lot of attention in the JavaScript field. The most prominent advantage of DI is the development of reusable and testable code units. This article explains the implementation mechanism of DI with simple code...
With AngularJS's popularity, dependency injection has attracted a lot of attention in the JavaScript field. The most prominent advantage of DI is the development of reusable and testable code units. This article explains the implementation mechanism of DI with simple code. For more information about the advantages and disadvantages of DI, see the article "when to use dependency injection.
A basic DI use case
Each module declares its own dependencies and provides its own services. For example:
di.service('foo', ['bar'], function foo(bar){ function Foo(){ this.bar = bar; } this.prototype.greeting = function(){ console.log('hello, world'); } return Foo;}); var foo = di.container.get('foo');foo.greeting();
Note the differences between dependency injection and CommonJS (or AMD). foo only needs to declare its dependency bar and does not need to be obtained proactively. This makes function foo completely ignorant of the dependency location and construction method. function foo becomes a testable and reusable code unit.
DI Framework Design
Service Registration and use should be performed in different periods. As a special dependency solution tool, DI framework divides the life cycle of software units into registration and operation stages. In the above example, the foo and bar services are provided in the registration phase, and these services are obtained and used in the runtime phase. Most DI frameworks adopt the lazy construction policy, which also avoids the difficulty of constructing at the registration stage.
Service customization can be performed before the running phase after the registration phase. AngularJS 1 introduces the configuration phase to customize these services. Its Provider can be understood as a special factory object. BottleJS uses modifiers and middleware to support service customization.
Use IoC containers to index service instances or storage service providers. When someone provides a service, it is added to the container. When someone uses the service, it searches for the provider from the container and generates a service instance. Normally, service instances can be cached.
Implementation of DI framework
First, implement the most common interface function. service (), which is used to register a service constructor. The passed function will be operated by the new operation.
var di = { container: {}};di.service = function(name, Constructor) { defineLazyProperty(name, () => new Constructor());}; function defineLazyProperty(name, getter){ Object.defineProperty(di.container, name, { configurable: true, get: function() { var obj = getter(container); Object.defineProperty(di.container, name, { configurable: false value: obj }); return obj; } });}
Object. defineProperty is used for service caching. The constructor is called only when the service is built for the first time. Subsequent access is to directly read the properties of the IoC container. It is compatible with ES5 standard methods. With the defineLazyProperty () method, these common registration interface implementations are very intuitive:
di.factory = function(name, factory) { return defineLazyProperty(name, factory);};di.provider = function(name, Provider) { return defineLazyProperty(name, function(){ var provider = new Provider(); return provider.$get(); });};di.value = function(name, val) { return defineLazyProperty(name, () => val);};
The service customization interface will not be repeated. It is worth mentioning that unified service customization requires a unified service construction method, rather than directly calling. defineLazyProperty () to generate attributes. In AngularJS, these policies are implemented by providers, and all other service registration methods are implemented by providers.
The above content is implemented by JavaScript dependency injection. For more information, see PHP Chinese website (www.php1.cn )!