How does AngularJS deal with these two things? When a given service is required, through the DI mechanism of the framework, AngularJS resolves all of its dependencies and instantiates it by passing them to the factory function, which encapsulates the logic for its creation. The factory function is passed as the second argument to the factory and service methods. The provider method allows definition of a service on lower level; the factory method there is the one under the $get property of the provider.

Just like AngularJS 1.x, Angular 2 tolerates this separation of concerns as well, so the core team kept the services. In contrast to AngularJS 1.x, the last major version of the framework provides a much simpler interface for the definition of services by allowing us to use plain ES2015 classes or ES5 constructor functions. We cannot escape from the fact that we need to explicitly state which services should be available for injection and somehow specify instructions for their instantiation. However, Angular 2 uses the ES2016 decorator’s syntax for this purpose instead of the methods familiar to us from AngularJS 1.x. This allows us to define the services in our applications as simple as ES2015 classes, with decorators for configuration of the DI:

import {Inject, Injectable} from 'angular2/core';

@Injectable()
class HttpService {
  constructor() { /* … */ }
}

@Injectable()
class User {
  constructor(private service: HttpService) {}
  save() {
    return this.service.post('/users')
      .then(res => {
        this.id = res.id;
        return this;
      });
  }
}

The alternative ECMAScript 5 syntax is:

var HttpService = ng.core.Class({
  constructor: function () {}
});
var User = ng.core.Class({
  constructor: [HttpService, function (service) {
    this.service = service;
  }],
  save: function () {
    return this.service.post('/users')
      .then(function (res) {
        this.id = res.id;
        return this;
      });
  }
});

Services are related to the components and the directives described in the previous sections. For developing highly coherent and reusable UI components, we need to move all the business-related logic to inside our services. And, in order to develop testable components, we need to take advantage of the DI mechanism for resolving all their dependencies.

A core difference between the services in Angular 2 and AngularJS 1.x is the way their dependencies are being resolved and represented internally. AngularJS 1.x is using strings for identifying the different services and the associated factories used for their instantiation. However, Angular 2 uses keys instead. Usually the keys are the types of the distinct services. Another core difference in the instantiation is the hierarchical structure of injectors, which encapsulate different dependency providers with different visibility.

Another distinction between the services in the last two major versions of the framework is the simplified syntax. Although Angular 2 uses ES2015 classes for the definition of our business logic, you can use ECMAScript 5 constructor functions as well or use the DSL provided by the framework. The DI in Angular 2 has a completely different syntax and has improved behavior by providing a consistent way of injecting dependencies. The syntax used in the preceding example uses ES2016 decorators,