AngularJSでよく見るDependency Injectionについて


### AngularJSでよく見かける書き方
```javascript
var myModule = angular.module('myModule', []);
```

とか、

```javascript
myModule.factory('greeter', function($window) {
return {
  greet: function(text) {
    $window.alert(text);
  }
};
});
```

というようにAngularJSでは独特の書き方をします。
このような書き方はDependency Injection(DI)という書き方だそうです。

AngularJSでのDIに関するドキュメント
https://docs.angularjs.org/guide/di

AngularJSでのDI部分のコード
https://github.com/angular/angular.js/blob/master/src/auto/injector.js

### DIについて

![img01.jpg](data:image/jpeg;base64,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)

http://www.amazon.co.jp/dp/4844336681/ref=cm_sw_r_tw_dp_nTJhub1X55QMC

AngularJSリファレンスという本でもDIについて解説がされています(DIとは、P.129)。

> DI(Dependency Injection)とは、あるコンポーネントから別のコンポーネントを利用する際に直接コンポーネントを呼び出すコードを記述するのではなく、設定ファイルやアノテーション機能を使ってコンポーネント間の依存関係を記述し、実行時に依存関係を解決するというデザインパターンです。

DIについて色々と詳しく書かれているので、興味がある人は是非読むのをオススメします。

普通書くときにコンポーネントを直接呼び出すのに慣れています。
1 - 依存関係を記述し、 2 - 実行時に依存関係を記述するという2段感あると一気に複雑に思えます。

### 簡易版AngularJSでDenpendency Injectionを体験する

http://merrickchristensen.com/articles/javascript-dependency-injection.html

AngularJS式Injectionを解説しているブログがありましたので、実際試し、メモしました。

```javascript
var WelcomeController = function (Greeter) {
  /** I want a different Greeter injected dynamically. **/
    Greeter.greet();
};
```

AngularJSでは引数の名前がdependencyの名前であります。
引数の名前は重要で、実際のdependencyとdepencyの名前が関連付けられます。

WelocomControlleが動くようにDIを作ってみます。

DIの機能として、1 - 依存関係を記述するメソッドと 2 - 依存関係を実行するメソッドが必要となります。

1 - 依存関係を記述するメソッド

```javascript
var Injector = {
	depnedencies : {},
	register     : function(name, dependency){
		this.depnedencies[name] = dependency;
	}
}

var RobotGreeter = {
  greet: function() {
    return 'Domo Arigato';
  }
};

Injector.register('Greeter', RobotGreeter);
```

RobertGreeterというオブジェクトを'greeter'として依存関係を登録する。

2 - 依存関係を実行するメソッド

```javascript
var Injector = {
	depnedencies : {},
	register     : function(name, dependency){
		this.depnedencies[name] = dependency;
	},
	process : function(target){
		
	}
}

Injector.register('Greeter', RobotGreeter);
Injector.process(WelcomeController);
```

WelcomeControllerを実行します。

どのように実行するか、、、という問題が出てきます。

```javascript
var Injector = {

    dependencies: {},

    process: function(target) {
        var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
        var text = target.toString();
        var args = text.match(FN_ARGS)[1].split(',');

        target.apply(target, this.getDependencies(args));
    },

    getDependencies: function(arr) {
        var self = this;
        return arr.map(function(value) {
            return self.dependencies[value];
        });            
    },

    register: function(name, dependency) {
        this.dependencies[name] = dependency;
    }

};

```

processでは、正規表現をつかって関数の引数を取ります。
applyで関数に引数を代入します。

サンプルはこんな感じでした。

### DIを利用してCanvasを描画する。
```javascript
// DI

var Injector = {
    
    dependencies: {},
    
    process: function(target) {
        var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
        var FN_ARG_SPLIT = /,/;
        var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
        var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
        var text = target.toString();
        var args = text.match(FN_ARGS)[1].split(',');
      
        var a = this.getDependencies(args);
        console.log(target);
        console.log("-----\n");
        console.log(a);
        
        target.apply(this, a);
    },
    
    getDependencies: function(arr) {
        var self = this;
        return arr.map(function(value) {
            
            return self.dependencies[value];
        });            
    },
    
    register: function(name, dependency) {
        this.dependencies[name] = dependency;
    }

};

// ============================
//         Canvasアプリ
// ============================

var CanvasApp = {
  width  : null,
  height : null,
  canvas : null,
  ctx    : null,
  
  setup  : function(){
    this.width  = window.innerWidth;
    this.height = window.innerHeight;
    this.canvas = document.getElementById('c');
    this.canvas.width = this.width;
    this.canvas.height = this.height;
    
    this.ctx = this.canvas.getContext('2d');
  },
  draw   : function(){
    this.ctx.fillStyle = '#ff0000';
    this.ctx.fillRect(100, 100, 100, 100);
  }
};

// ============================
//        コントローラ
// ============================

var CanvasAppController = function (paintApp) {
    paintApp.setup();
    paintApp.draw();
};

// 1.dependencyをに'paintApp'としてCanvasAppを登録
Injector.register('paintApp', CanvasApp);

// 2.実行する
Injector.process(CanvasAppController);

```

結果は下のリンクから見ることができます。
http://codepen.io/kenjiSpecial/pen/GBpnE



DIを知ったつもりになりましたー
AngularJS色々と学ぶことが多いです。。