File Coverage

blib/lib/Mojolicious/Services.pm
Criterion Covered Total %
statement 49 63 77.7
branch 13 22 59.0
condition 1 3 33.3
subroutine 9 10 90.0
pod 4 4 100.0
total 76 102 74.5


line stmt bran cond sub pod time code
1             package Mojolicious::Services;
2 2     2   107533 use Mojo::Base 'Mojolicious::Service';
  2         222745  
  2         15  
3 2     2   208 use Carp 'croak';
  2         4  
  2         76  
4 2     2   758 use Mojo::Loader qw/find_modules load_class/;
  2         47544  
  2         123  
5 2     2   14 use Mojo::Util qw/camelize decamelize/;
  2         4  
  2         70  
6 2     2   8 use Scalar::Util;
  2         4  
  2         1473  
7              
8             our $VERSION = '2.1.0';
9              
10             has services => sub{{}};
11             has namespaces => sub{["Mojolicious::Service"]};
12             has lazy => 1;
13              
14              
15             sub load_service{
16 1     1 1 2 my ($self, $name) = @_;
17            
18             # Try all namespaces and full module name
19 1 50       5 my $suffix = $name =~ /^[a-z0-9]/ ? camelize $name : $name;
20 1         2 my @classes = map {"${_}::$suffix"} @{$self->namespaces};
  2         18  
  1         3  
21 1         3 for my $class (@classes, $name){
22 3 100       107 if(_load($class)){
23 1         28 my $service = $class->new(models => $self->models, dbi => $self->dbi, app => $self->app, parent => $self);
24 1         27 Scalar::Util::weaken $service->{app};
25 1         3 Scalar::Util::weaken $service->{models};
26 1         3 Scalar::Util::weaken $service->{dbi};
27 1         2 Scalar::Util::weaken $service->{parent};
28 1         6 $self->service($name, $service);
29 1         2 return $service;
30             }
31             }
32            
33             # Not found
34 0         0 die qq{Service "$name" missing, maybe you need to install it?\n};
35             }
36              
37             sub load_all_service{
38 0     0 1 0 my $self = shift;
39 0         0 foreach(map{find_modules($_)}@{$self->namespaces}){
  0         0  
  0         0  
40 0         0 $_ =~ /^.+\:([^\:]+)$/;
41 0         0 my $name = decamelize($1);
42 0 0       0 if(_load($_)){
43 0         0 my $service = $_->new(models => $self->models, dbi => $self->dbi, app => $self->app, parent => $self);
44 0         0 Scalar::Util::weaken $service->{app};
45 0         0 Scalar::Util::weaken $service->{models};
46 0         0 Scalar::Util::weaken $service->{dbi};
47 0         0 Scalar::Util::weaken $service->{parent};
48 0         0 $self->service($name, $service);
49             }
50             }
51             }
52              
53             sub new{
54 1     1 1 84 my ($self, $conf) = @_;
55 1 50       5 my $namespaces = delete $conf->{namespaces} if($conf->{namespaces});
56 1         12 $self = $self->SUPER::new($conf);
57 1 50 33     18 if($namespaces && ref $namespaces eq "ARRAY"){
58 1         2 unshift(@{$self->namespaces}, $_) for(reverse @{$namespaces});
  1         3  
  1         16  
59             }
60 1 50       4 $self->load_all_service unless($self->lazy);
61 1         9 return $self;
62             }
63              
64             sub service{
65 2     2 1 8 my ($self, $name, $service) = @_;
66            
67             # Set service
68 2 100       5 if($service){
69 1         3 $self->services->{$name} = $service;
70 1         5 return $self;
71             }
72            
73 1 50       4 unless($self->services->{$name}){
74 1         4 $self->load_service($name);
75             }
76            
77             # Check services existence
78 1 50       3 croak qq{service "$name" is not yet created } unless($self->services->{$name});
79            
80             # Get service
81 1         6 return $self->services->{$name};
82             }
83              
84              
85              
86             sub _load{
87 3     3   6 my $module = shift;
88 3 100       7 return $module->isa('Mojolicious::Service') unless(my $e = load_class $module);
89 1 50       254 ref $e ? die $e : return undef;
90             }
91              
92              
93             =encoding utf8
94              
95             =head1 NAME
96              
97             Mojolicious::Services - Mojolicious::Services 是为Mojolicious框架提供的Service管理插件。
98              
99             =head1 SYNOPSIS
100              
101             use Mojolicious::services
102             my $service_manage = Mojolicious::services->new({
103             dbi=>DBIx::Custom->new(),
104             models=>{},
105             namespaces=>s["Mojolicious::Service"],
106             lazy => 1
107             });
108            
109             ## fetch a service
110             my $user_service = $service_manage->service("user");
111              
112              
113              
114             =head1 DESCRIPTION
115              
116             Mojolicious::services是为Mojolicious框架提供Service支持的模块。
117              
118              
119             =head1 ATTRIBUTES
120              
121             Mojolicious::services 从 Mojolicious::Service中继承了所有属性,并实现以下属性。
122              
123              
124             =head2 services
125              
126             存储service的属性。
127              
128              
129             =head2 namespaces
130              
131             namespaces 用于说明service类所在的命名空间,这个属性的值是一个arrayref 类型的值,支持在多个命名空间中查找service。
132              
133              
134             =head2 lazy
135              
136             用于说明是否启用懒加载模式。
137             如果值为true则启用懒加载,只有在实际请求一个service时才加载其类并实例化一个service对象。
138             如果为flase则在创建Mojolicious::services时加载所有service类并实例化成对象。
139              
140              
141             =head1 METHODS
142              
143             Mojolicious::services 从 Mojolicious::Service中继承了所有方法,并实现以下方法。
144              
145             =head2 load_service
146              
147             根据service的名字加载service。
148              
149              
150              
151             =head2 load_all_service
152              
153             加载 namespaces 属性指定的所有命名空间下的所有service,并实例化。
154             注:只有在非懒加载模式的初始化阶段才会调用这个方法。
155              
156              
157              
158             =head2 new
159              
160             生成一个新的Mojolicious::services对象。
161              
162              
163             =head2 service
164              
165             根据 service 的名称从 services 属性中获取 service。如果在 services 属性中不存在对应的键,则尝试从 namespaces 属性指定的命名空间中加载并实例化一个service。如果尝试加载后仍获取失败,则返回 undef。
166              
167              
168              
169             =head1 AUTHOR
170              
171             wfso, C<< <461663376@qq.com> >>
172              
173             =head1 BUGS
174              
175             Please report any bugs or feature requests to C, or through
176             the web interface at L. I will be notified, and then you'll
177             automatically be notified of progress on your bug as I make changes.
178              
179              
180              
181              
182             =head1 SUPPORT
183              
184             You can find documentation for this module with the perldoc command.
185              
186             perldoc Mojolicious::services
187              
188              
189             You can also look for information at:
190              
191             =over 4
192              
193             =item * RT: CPAN's request tracker (report bugs here)
194              
195             L
196              
197             =item * AnnoCPAN: Annotated CPAN documentation
198              
199             L
200              
201             =item * CPAN Ratings
202              
203             L
204              
205             =item * Search CPAN
206              
207             L
208              
209             =back
210              
211              
212             =cut
213              
214             1; # End of Mojolicious::services