JavaScriptで動くDIコンテナに機能を追加しました。
以前作成したJavaScriptで動くDIコンテナにこっそり機能を追加していたので公開してみます。
新機能は次の3つです。
コンポーネント定義の列挙
Container#eachComponentDef()、Container#eachComponentDefs()で登録済みのコンポーネント定義を列挙します。DIコンテナの基本機能ですね。どちらも引数でコールバック関数を指定します。
- Container#eachComponentDef()
- Container#eachComponentDef()
var stdout = document.getElementById( "stdout" ); // クラス function Kitten() {} Kitten.prototype = { getName: function () { return this.name; } }; // コンテナを作成。 var c = new container.Container( function( binder ) { binder.bind( "kitten" ).to( Kitten ).inject( { "name": "mii" } ); binder.bind( "kitten" ).to( Kitten ).inject( { "name": "shiro" } ); binder.bind( "kitten" ).to( Kitten ).inject( { "name": "kuro" } ); binder.bind( "tiger" ).to( Kitten ).inject( { "name": "tora" } ); }); // コンポーネント定義を列挙 c.eachComponentDef( function( name, def ) { // 第1引数はコンポーネント名 // 第2引数はコンポーネント定義 stdout.innerHTML += name + ":" + def[container.Annotation.Container][container.Annotation.Inject]["name"] + "<br/>"; }); stdout.innerHTML += "<br/>"; // コンポーネント定義を名前ごとに列挙 c.eachComponentDefs( function( name, defs ) { // 第1引数はコンポーネント名 // 第2引数はコンポーネント定義の配列 stdout.innerHTML += name + ":" + defs.length + "<br/>"; });
関数実行結果のインジェクション
決められた手順で関数をインジェクションすることで、関数の実行結果をインジェクションできるようにしました。インジェクションする値を実行時に決定したい場合に使用します。
var c = new container.Container( function( binder ) { binder.bind( "kitten" ).to( Kitten ).inject( { // 関数の戻り値をインジェクションする "name": container.provides( function () { return location.hash || "mii"; // URLのロケーションを名前にする。 }) }); }); var kitten = c.get("kitten"); stdout.innerHTML += kitten.getName();
EagerSingletonスコープ
コンポーネントのスコープに「EagerSingleton」を追加しました。「EagerSingleton」スコープとされたコンポーネントはコンテナの作成時に生成されます。(Singletonの場合、コンテナから初めてコンポーネントを取得した際に生成される。)これを利用して、コンテナに登録しておくだけで効果を発揮するコンポーネントを作成できるようになります。
// コンテナを作成。 var c = new container.Container( function( binder ) { binder.bind( "kitten" ).to( Kitten ).inject( { "name": "mii" } ) .scope( container.Scope.EagerSingleton ) // EagerSingletonとする .initialize( function( obj, container ) { // コンテナ生成時にコンポーネントも作成される。 // コンポーネントを取得しなくても以下の処理が実行される。 stdout.innerHTML += obj.getName() + "<br/>"; } ); });
ダウンロード
ダウンロードはこちらから。
container.js(コンテナ本体) ver0.2.0
テストケースの実行結果
- ※動作確認はIE6とFireFoxで行っています。
- ※仕様を追加したのでマイナーバージョンを上げて0.2.0としました。
あとがき
趣味アプリで使おうと画策中だけど、ネタがないのです。それなりに大きいプログラムじゃないと使う意味ない気がするし。むー。
あと、そろそろ名前付けたい。「JavaScriptで動くDIコンテナ」とか書くの面倒になってきた。