AngularJS: сервисы, фабрики, провайдеры
Чтоже это за странные service, factory и provider. Казалось бы - выполняют почти одну и туже функцию, подключаются через DI. Зачем их так много?
На абстрактный пример можно глянуть тут (к слову, автор привел очень хороший пример).
Но никто не рассказывает, зачем оно в реальной практике нужно.
Сервис
Он чаще всего используется для создания разделяемого ресурса.
var constructor = function constructor() {
this.foo = 'foo'
this.bar = function bar() {
}
}
.service('someService', constructor)
Когда сервис создается первый раз, то выполняется
var someServiceImpl = new constructor()
И в дальнейшем при подключении зависимостей через DI в объекты будет всегда передаваться someServiceImpl.
Фабрика
это более продвинутая конструкция. Она не является разделяемым ресурсом сама по себе. При каждом использовании фабрики через DI ее значение - это результат вызова фабричной функции.
var factoryFn = function () {
var someClass = function() {}
return someClass;
}
.factory('someFactory', factoryFn)
При первом инстанцировании фабрики будет вызвана функция factoryFn и ее результат - это уже и есть разделяемое между всеми участниками системы значение.
Свое применения фабрика находит в первую очередь для реализации моделей. Как в примере выше. Создается и описывается класс модели someClass и фабрика при инстанцировании возвращает ссылку на него. В последующем можно использовать этот класс как конструктор объектов.
.controller('someController', ['someFactory', function(someFactory) {
// Тут мы успешно инстанцируем новый объект someClass
var someClassImpl = new someFactory();
}])
Провайдер
Это тоже фабрика. Но более продвинутаця. Так же точно при первом инстанцировании провайдера выполняется некая функция и ее результат становится разделяемым значением.
Но вся мощь провайдеров в том, что их можно конфигурировать (в отличие от фабрик или сервисов). Т.е. на этапе инициализации вашего приложения можно передать провайдеру некоторые опции, которые нельзя указать в дальнейшем.
Как пример - библиотека для oauth-авторизации. на этапе конфигурирования в нее передаются токены.
var providerFn = function() {
var someModel = function() {
// это модель
}
this.configure = function() {
// делаем какую-то конфигурацию
}
this.$get = function() {
return new someModel()
}
}
.provider('someProvider', providerFn)
И теперь самое интересное: при подключении провайдера через DI в качестве разделяемого объекта будет выступать то, что вернула функция $get.
В то же время на этапе конфигурирования нам доступен сам инстанс providerFn и мы можем использовать его функционал по конфигурированияю
.config(['someProvider', function(someProvider) {
//...
someProvider.configure(options)
}])
Категории: Разработка