Maple DICon、ひとまず完成

ひとまず動いた。テストが不十分なので残念ながらまだだせませんが、こんな感じで動くというのを書きます。

Injection対象となるのは普通のクラスで、以下のルールだけ守っておくこと。

  • セットしたい変数に対して、「set+変数名」の形のsetterがあること

これさえ守れば以下のiniファイルでSetter Injectionできます。

[test1:jp.kunit.test1]
name = kunit
email = kunit@kunit.jp

[test2:jp.kunit.test2]
arraytest = "aaa,bbb,ccc"
reftest = "ref:test1"

iniファイルのルールは以下の通り。

  • セクション名は「エイリアス:クラス」
  • 「クラス」は以下のルールで実ファイルにマッピングされる
    • ファイルをサーチする基準ディレクトリは「COMPONENTS_DIR」定数で指定(例えばcomponents/)
    • 「.」で分割後、最後の1つを除いた分をディレクトリにする。「jp.kunit.test1」だと、「components/jp/kunit/」にマッピングされる。
    • クラス名は「.」で分割し、それぞれの先頭文字列を大文字にしたものになる。「jp.kunit.test1」だと、「Jp_Kunit_Test1」になる。
    • クラスを含むファイル名は上記のディレクトリと「クラス名.class.php」で決まる。「jp.kunit.test1」だと「components/jp/kunit/Jp_Kunit_Test1.class.php」になる。
  • それぞれの「キー = 値」の部分は、「値」が「ref:」で始まっていたら、別セクションで定義された「エイリアス」をみて、そのクラスのインスタンスを「キー」に対応する変数にInjectionする。
  • 「値」が「ref:」で始まってなければ普通の値として「キー」に対応する変数にInjectionする。
  • 「値」がカンマで区切られていれば、配列として「キー」に対応する変数にInjectionする。

DIContainerの使い方は以下のようになります。(基本的にSeasarと同じ)このようにすることにより、「$test1」には2つの値があらかじめセットされたオブジェクトが、「$test2」には「$test1」への参照を含んだオブジェクトが取得できます。

<?php
require_once "BeanUtils.class.php";
require_once "DIContainerFactory.class.php";

define('DICON_FILE', 'xxx/yyy/zzz/dicon.ini');
define('COMPONENTS_DIR', 'components/');

$container =& DIContainerFactory::create(DICON_FILE);

$test1 =& $container->getComponent("test1");
$test2 =& $container->getComponent("test2");

print_r($test1);
print_r($test2);
?>

明日の晩にMapleとは切り離してDICon部分だけαリリースしようかなと思っています。現時点では私の知識だけでつくってるので、リリースしたものを見ていただいてこうやったほうがいいよ!とかあればご意見がいただければと。

Maple本体は、DIconの取り込みと関西オープンソース2004でいただいたご要望をとりこんで、beta1として近いうちにリリースしたいと思います。