読者です 読者をやめる 読者になる 読者になる

Catalyst::Model::MultiAdaptor - 複数のPOPOモデルをCatalystモデルにラップする

catalyst

Catalyst::Model::Adaptorは素晴らしいモジュールなのですが、Catalyst::Model::Adaptorは、ラッパ(Adaptor)とPlainなCatalystモデルが1:1対応するために、ラッパを複数作る必要があるのが大変でした。

そこで、複数のPOPOモデルをロードするモジュールを作ってみました。
http://github.com/dann/catalyst-model-multiadaptor/tree/master

モデル毎にconfigurationをコンストラクタにHashで渡す事ができるようにしています。DBへの接続のための情報などを渡すのがいいです。

では、実際に使い方を説明します。
まずラップしたいPlainなPerlのクラス(POPO Model)を作ります。

  package MyApp::Service::SomeClass;
  use Moose;
 
  has 'id' => (
      is => 'rw',
  );
 
  1;
 
 
  package MyApp::Service::AnotherClass;
  use Moose;
 
  has 'host' => (
      is => 'rw',
  );
 
  1;


次は、上記のPOPOモデルをCatalystのModelにラップします。ラップしたいモデルのパッケージを指定すると、そのパッケージ以下のモデルがCatalystのモデルになります。

  package MyApp::Web::Model::Service;
  use base 'Catalyst::Model::MultiAdaptor';
  __PACKAGE__->config(
      package => 'MyApp::Service',
      config => {
          'SomeClass' => {
              id => 1,
          },
          'AnotherClass' => {
                host => 'example',
          },
  );
 
  1;
||< 

上記のようにラップすることで、ラップしたモデルは以下のように使えます。

>|perl|
  sub action: Whatever {
      my ($self, $c) = @_;
      my $someclass = $c->model(&#39;Service::SomeClass&#39;);
      $someclass->method; #yay
  }
 
  sub another_action: Whatever {
      my ($self, $c) = @_;
      my $anotherclass = $c->model(&#39;Service::AnotherClass&#39;);
      $anotherclass->method; #yay
  }

configをクラス毎に設定する事で、そのconfigをClassにwiringします。configのDIをしているということになります。また、ラップしたモデルのライフサイクルはSingletonになるのでリクエストの度にnewすることはしません。

Catalyst::Model::Adaptorだと、モデルの数だけラッパを作らなければいけないのですが、その点が解消できます。また、Configurationを渡せるのでクラス毎の初期設定を渡す事ができます。

# Catalyst::Model::Loader改です。