/
container.txt
160 lines (123 loc) · 4.69 KB
/
container.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
kamuiでは色々なビジネスロジックの処理をまとめたクラスをcontainerというところから
取り出して使うことをおすすめしています。
デフォルトのcontainerとしてはconfとhomeが存在します。
confは名前のとおりアプリケーション用の設定情報にアクセスし、
homeはアプリケーションが配置されているhomeディレクトリ情報にアクセスします。
Kamui::Containerではそれ以外にも様々なロジックを格納し
好きな場所でそのロジックを取り出すことができます。
Containerをつかうには
>||
package MyApp::Container;
use Kamui::Container -base;
1;
||<
このようなクラスを定義します。
KamuiではContainerクラスは必ず定義する必要があります。
これだけでconf/homeは自動で定義されます。
ロジックをContainerに登録するには以下のようにします。
>||
package MyApp::Container;
use Kamui::Container -base;
register foo => sub {'foo'};
1;
||<
まずKamui::Containerをuseする時に引数として-baseを指定します。
-baseと指定することで、このクラスがContainerのベースクラスとなり、register関数がexportされます。
そして、このようにregisterという関数を使うことでContainerクラスにロジックを登録することができます。
register関数の第一引数にロジックにアクセスする名前を定義し、
第二引数にそのロジックのコンストラクタを定義します。
第二引数に定義しているのが、実際のロジックにアクセスするためのコンストラクタということに注意しくてください。
なので、
>||
package MyApp::Container;
use Kamui::Container -base;
use Foo;
register foo => sub {
Foo->new;
};
1;
||<
多くの場合はこのようにオブジェクトのインスタンスを作るかと思います。
定義したcontainer情報は
>||
package MyAPP::Demo;
use MyAPP::Container;
sub run {
container('foo');
}
1;
||<
このようにすればアクセスすることが可能です。
Kamui::Containerを使ってつくったMyAPP::Containerをuseすると、
自動でcontainerという関数がuseしたクラスにexportされます。
>||
container('foo')
||<
と、初回呼び出した段階で登録されているコンストラクタが一度実行されます。
二度目以降のアクセスでは、初回に実行されたコンストラクタの情報がキャッシュされているので効率的です。
Containerにビジネスロジックをどんどん登録することで、
自由に好きな場所からビジネスロジックにアクセスすることが可能ですが、
Kamui::Containerではわざわざregister関数を使ってロジックを登録しなくても
簡単にビジネスロジックにアクセスすることが可能です。
例えば、
>||
package MyAPP::Api::Foo;
use strict;
use warnings;
sub new {
my $class = shift;
bless {}, $class;
}
sub foo {'foo'}
1;
||<
このようなビジネスロジックの処理をまとめたクラスがあるとします。
このクラスにアクセスするときにregister関数を使う場合
>||
package MyAPP::Container;
use Kamui::Container -base;
use MyAPP::Api::Foo;
register api_foo => sub {
MyAPP::Api::Foo->new;
};
1
||<
このように書きます。
しかしいちいちregisterで登録するのが面倒なので別の方法を使います。
Kamui::Containerは
>||
package MyAPP::Demo;
use MyAPP::Container qw/api/;
sub run {
api('Foo')->foo;
}
1;
||<
このようにContainerクラスをuseす時に文字列を指定すると
指定した文字列の名前の関数がexportされます。
exportされた関数経由でビジネスロジックにアクセスします。
この例の場合、apiという文字列を指定しているので
apiという関数がexportされます。
exportされたapiという関数は引数で受け取った文字列を使って内部では
MyAPP::Api::Fooというクラスをuseし、newメソッド(コンストラクタ)を実行し
MyAPP::APi::Fooというクラスのインスタンスをキャッシュします。
今回の例ではapiという文字列を指定してapiという関数をexportしましたが、
>||
package MyAPP::Command::Foo;
use strict;
use warnings;
sub new {
my $class = shift;
bless {}, $class;
}
sub foo {'foo'}
1;
package MyAPP::Demo;
use MyAPP::Container qw/command/;
sub run {
command('Foo')->foo;
}
1;
||<
とcommandという文字列を指定するとcommandという名前で関数がexportされ、
MyAPP::Command::*というクラスにアクセスすることが可能になります。