AngularJSにおけるService、Provider、Factoryの比較とコード例
AngularJSにおけるService、Provider、Factoryの違い
AngularJSのDependency Injection (依存性注入)
AngularJSでは、依存性注入という概念を用いて、オブジェクト間の依存関係を管理します。これにより、コードのモジュール化とテスト性を向上させることができます。
Service、Provider、Factoryの役割
これら3つの概念は、AngularJSのサービスを作成するための手段です。それぞれ異なるライフサイクルと使用方法を持ちます。
Service
- ライフサイクル: アプリケーションの起動時にインスタンス化され、アプリケーションの終了まで存在します。
- 用途: 汎用的なサービスや、アプリケーション全体で共有したいデータを保持するサービスに適しています。
- 例:
angular.module('myApp', [])
.service('myService', function() {
var data = 'hello';
this.getData = function() {
return data;
};
});
Provider
- ライフサイクル: アプリケーションの起動時にインスタンス化され、
$get
メソッドが呼ばれるまでは、設定や初期化の処理に使用されます。 - 用途: サービスの初期化や設定をカスタマイズしたい場合、または、サービスのインスタンス化を遅延させたい場合に適しています。
angular.module('myApp', [])
.provider('myProvider', function() {
var baseUrl = 'http://example.com';
this.setBaseUrl = function(newBaseUrl) {
baseUrl = newBaseUrl;
};
this.$get = function() {
return {
getData: function() {
return $http.get(baseUrl + '/data').then(function(response) {
return response.data;
});
}
};
};
});
Factory
- 用途: Serviceと同様ですが、より柔軟なオブジェクトの返却が可能です。
angular.module('myApp', [])
.factory('myFactory', function() {
return {
getData: function() {
return 'hello';
},
otherMethod: function() {
// ...
}
};
});
いつどの概念を使うべきか
- Service: 汎用的なサービスや、アプリケーション全体で共有したいデータを保持する場合。
- Factory: 柔軟なオブジェクトを返したい場合、または、Serviceと同様の機能が必要な場合。
特徴 | Service | Provider | Factory |
---|---|---|---|
ライフサイクル | アプリケーションの起動時にインスタンス化され、アプリケーションの終了まで存在する。 | アプリケーションの起動時にインスタンス化されるが、$get メソッドが呼ばれるまでは、設定や初期化の処理に使用される。 | Serviceと同じく、アプリケーションの起動時にインスタンス化され、アプリケーションの終了まで存在する。 |
用途 | 汎用的なサービスや、アプリケーション全体で共有したいデータを保持するサービスに適している。 | サービスの初期化や設定をカスタマイズしたい場合、または、サービスのインスタンス化を遅延させたい場合に適している。 | Serviceと同様ですが、より柔軟なオブジェクトの返却が可能です。 |
返り値 | 常にオブジェクトを返す。 | $get メソッドが返すオブジェクト。 | 任意の値を返すことができる。 |
コード例
angular.module('myApp', [])
.service('myService', function() {
var data = 'hello';
this.getData = function() {
return data;
};
});
angular.module('myApp', [])
.provider('myProvider', function() {
var baseUrl = 'http://example.com';
this.setBaseUrl = function(newBaseUrl) {
baseUrl = newBaseUrl;
};
this.$get = function() {
return {
getData: function() {
return $http.get(baseUrl + '/data').then(function(response) {
return response.data;
});
}
};
};
});
angular.module('myApp', [])
.factory('myFactory', function() {
return {
getData: function() {
return 'hello';
},
otherMethod: function() {
// ...
}
};
});
使用例
Class-based Services
AngularJS 1.5以降、クラスベースのサービスが導入されました。これは、ES6のクラス構文を使用してサービスを定義する方法です。
class MyService {
constructor() {
this.data = 'hello';
}
getData() {
return this.data;
}
}
angular.module('myApp', [])
.service('myService', MyService);
Constant
constant
は、アプリケーションの起動時に評価され、変更できない値を定義するためのものです。
angular.module('myApp', [])
.constant('MY_CONSTANT', 'hello');
Value
angular.module('myApp', [])
.value('myValue', 'hello');
Decorator
decorator
は、既存のサービスを装飾して、その挙動を変更するためのものです。
angular.module('myApp', [])
.decorator('myService', function($delegate) {
$delegate.getData = function() {
return 'modified data';
};
});
Providerの直接使用
Provider
は、サービスの初期化や設定をカスタマイズするためのものです。直接使用することもできます。
angular.module('myApp', [])
.config(function(myProvider) {
myProvider.setBaseUrl('http://new.example.com');
});
$injector
$injector
は、サービスの取得や注入を行うためのAngularJSの組み込みサービスです。
angular.module('myApp', [])
.controller('MyController', function($injector) {
var myService = $injector.get('myService');
// ...
});
どの方法を使うべきか
- Provider: サービスの初期化や設定をカスタマイズしたい場合。
- Class-based Services: ES6のクラス構文を使用したい場合。
- Constant: 変更できない値を定義する場合。
- Value: 変更可能な値を定義する場合。
- Decorator: 既存のサービスの挙動を変更する場合。
- $injector: サービスの取得や注入を行う場合。
angularjs dependency-injection angularjs-service