Hatena::Groupcatalyst

dann@catalyst このページをアンテナに追加 RSSフィード

2008-04-04

yasnippet for vimが欲しい

04:52 |  yasnippet for vimが欲しい - dann@catalyst を含むブックマーク はてなブックマーク -  yasnippet for vimが欲しい - dann@catalyst  yasnippet for vimが欲しい - dann@catalyst のブックマークコメント

snippetsEmuはsnippetが書きにくくて、気軽に追加しようとする気になれないのが最大の欠点。Perl系のsnippetをまとめて登録したいんだけど。

Wiki+Blogみたいなのでやりたいな

04:35 |  Wiki+Blogみたいなのでやりたいな - dann@catalyst を含むブックマーク はてなブックマーク -  Wiki+Blogみたいなのでやりたいな - dann@catalyst  Wiki+Blogみたいなのでやりたいな - dann@catalyst のブックマークコメント

日記でやるものではない気がする俺ガイル

Perlのプラグイン機構のお勉強

| 03:17 |  Perlのプラグイン機構のお勉強 - dann@catalyst を含むブックマーク はてなブックマーク -  Perlのプラグイン機構のお勉強 - dann@catalyst  Perlのプラグイン機構のお勉強 - dann@catalyst のブックマークコメント

後でまじめに見てみる。Perlのリフレクション機構も後で。

Mooseへ移行

| 03:17 |  Mooseへ移行 - dann@catalyst を含むブックマーク はてなブックマーク -  Mooseへ移行 - dann@catalyst  Mooseへ移行 - dann@catalyst のブックマークコメント

Mooseに移行。requiredでチェックできるのはなかなか便利。before,afterもキャッシング・トランザクション周りを綺麗に扱えそうなので、結構面白そう。

Bread::Boardを使いやすくするには、Attributeを理解しないといけないな。Attributeってメソッドにしかつけられないのかな。それだとなんか足りないな。

cho45さんのstarter

| 03:17 |  cho45さんのstarter - dann@catalyst を含むブックマーク はてなブックマーク -  cho45さんのstarter - dann@catalyst  cho45さんのstarter - dann@catalyst のブックマークコメント

http://github.com/cho45/catstarter-pl/tree/master/catstarter.pl

Path::Classの使い方がわかったから暇あったら取り込もう。templateのほうを期待!

Catalyst+ DIでアプリケーションのCatalystへの依存を切り離す

| 00:31 |  Catalyst+ DIでアプリケーションのCatalystへの依存を切り離す - dann@catalyst を含むブックマーク はてなブックマーク -  Catalyst+ DIでアプリケーションのCatalystへの依存を切り離す - dann@catalyst  Catalyst+ DIでアプリケーションのCatalystへの依存を切り離す - dann@catalyst のブックマークコメント

Catalyst中でDIコンテナを使い、CatalystからService、ModelクラスのCatalyst依存部分を切り離すようにする方法を以下に示します。

やることは至って単純で、

  • BaseのControllerでServiceContainerからServiceクラスを取得
  • ServiceContainerではモジュールのロードタイミングでDIコンテナを初期化しWiringをする

の二つだけです。

これによって、利用者はDIコンテナからServiceを取得すればよくなります。

BaseのController

package MyApp::Base::Web::Controller;
use base 'Catalyst::Controller';

sub service: Private {
    my ($self, $service_name) = @_;
    return MyApp::ServiceContainer->get($service_name);
}

1;

ServiceContainer.

package MyApp::ServiceContainer;
use strict;
use warnings;

use Bread::Board;

our $container;
BEGIN {
    $container = container 'AppContainer' => as {
         service 'Service::Blog' => (
             class     => 'MyApp::Service::Blog',
             lifecycle => 'Singleton',
         );
    };
}

sub get {
    my $class= shift;
    my $service_name = shift;
    $container->fetch($service_name)->get;
}

1;

利用する側のコード

Controller中で以下のように参照する。

$self->service('Service::Blog')->create_entry($title, $content);

これで、ServiceクラスはCatalystに依存することがなくなります。これにより、CatalystはWAFとしての役割にだけ集中すればよく、アプリケーション側はPOPOベースでドメインモデルを構築することに専念することができます。これによって、アプリケーションはCatalystからの依存関係を断ち切ることが出来るようになるため、Testabilityが高くなります。DIコンテナから参照できるオブジェクト(Service、Model)は、Catalystには依存していないため、CLIからもWebAPIからも使うことが出来ます。

ServiceContainerは、今は手で書いてますが、ここの部分は工夫の余地があります。Bread::Boardは旧世代のDIコンテナだという話を前に書きましたが、その理由はこのWiringする部分を一箇所で集中して書かなければいけないからです。JavaでいうAnnotationを使うと綺麗に解決できるので、おそらくPerlでもAttributeで解決できることなんだろうと思います。

DIコンテナはどのような形であるべきかについては、また後のエントリで書きたいと思います。自分がもう少しPerlが分かっていたら、解決策までコードベースで提示できそうなんですが、まだ大分Perlの知識が足りないですね...

トラックバック - http://catalyst.g.hatena.ne.jp/dann/20080404