File Coverage

blib/lib/IOC/Registry.pm
Criterion Covered Total %
statement 108 108 100.0
branch 41 42 97.6
condition 9 12 75.0
subroutine 20 20 100.0
pod 11 11 100.0
total 189 193 97.9


line stmt bran cond sub pod time code
1              
2             package IOC::Registry;
3              
4 10     10   69043 use strict;
  10         19  
  10         362  
5 10     10   52 use warnings;
  10         16  
  10         531  
6              
7             our $VERSION = '0.05';
8              
9 10     10   58 use Scalar::Util qw(blessed);
  10         18  
  10         1073  
10              
11 10     10   2453 use IOC::Exceptions;
  10         23  
  10         278  
12 10     10   3739 use IOC::Interfaces;
  10         27  
  10         344  
13              
14 10     10   11821 use IOC::Visitor::SearchForService;
  10         27  
  10         286  
15 10     10   24582 use IOC::Visitor::SearchForContainer;
  10         529  
  10         306  
16              
17 10     10   68 use base 'Class::StrongSingleton';
  10         62  
  10         14337  
18              
19             sub new {
20 30     30 1 2510 my ($_class) = @_;
21 30   33     179 my $class = ref($_class) || $_class;
22 30         159 my $registry = {
23             containers => {},
24             service_aliases => {}
25             };
26 30         85 bless($registry, $class);
27 30         267 $registry->_init();
28 30         2293 return $registry;
29             }
30              
31             # add and remove containers
32              
33             sub registerContainer {
34 35     35 1 752 my ($self, $container) = @_;
35 35 100 100     598 (blessed($container) && $container->isa('IOC::Container'))
36             || throw IOC::InsufficientArguments "You must supply a valid IOC::Container object";
37 31         153 my $name = $container->name();
38 31 100       71 (!exists ${$self->{containers}}{$name})
  31         285  
39             || throw IOC::ContainerAlreadyExists "Duplicate Container '$name'";
40 30         168 $self->{containers}->{$name} = $container;
41             }
42              
43             sub unregisterContainer {
44 6     6 1 227 my ($self, $container_or_name) = @_;
45 6 100       23 (defined($container_or_name)) || throw IOC::InsufficientArguments "You must supply a name or a container";
46 5         8 my $name;
47 5 100       16 if (ref($container_or_name)) {
48 3 100 100     47 (blessed($container_or_name) && $container_or_name->isa('IOC::Container'))
49             || throw IOC::InsufficientArguments "You must supply a valid IOC::Container object";
50 1         6 $name = $container_or_name->name();
51             }
52             else {
53 2         5 $name = $container_or_name;
54             }
55 3 100       6 (exists ${$self->{containers}}{$name})
  3         17  
56             || throw IOC::ContainerNotFound "Cannot unregister a container we do not have";
57 2         7 my $container = $self->{containers}->{$name};
58 2         6 delete $self->{containers}->{$name};
59 2         11 return $container;
60             }
61              
62             # fetching the containers
63              
64             sub getRegisteredContainer {
65 15     15 1 30535 my ($self, $name) = @_;
66 15 100       62 (defined($name)) || throw IOC::InsufficientArguments "You must supply a name of a container";
67 14 100       30 (exists ${$self->{containers}}{$name})
  14         97  
68             || throw IOC::ContainerNotFound "There is no container by the name '${name}'";
69 11         54 return $self->{containers}->{$name};
70             }
71              
72             sub getRegisteredContainerList {
73 8     8 1 8100 my ($self) = @_;
74 8         14 return keys %{$self->{containers}};
  8         85  
75             }
76              
77             sub hasRegisteredContainer {
78 5     5 1 1575 my ($self, $name) = @_;
79 5 100       24 (defined($name)) || throw IOC::InsufficientArguments "You must supply a name of a container";
80 4 100       5 return (exists ${$self->{containers}}{$name}) ? 1 : 0;
  4         30  
81             }
82              
83             # aliasing
84              
85             sub aliasService {
86 3     3 1 1464 my ($self, $real_path, $alias_path) = @_;
87 3 100 66     27 (defined($alias_path) && defined($real_path))
88             || throw IOC::InsufficientArguments "You must supply a alias path and a real path";
89 1         4 $self->{service_aliases}->{$alias_path} = $real_path;
90             }
91              
92             # locate Service by path
93              
94             sub locateService {
95 20     20 1 4132 my ($self, $path, @extra_args) = @_;
96 20 100       69 (defined($path)) || throw IOC::InsufficientArguments "You must supply a path to a service";
97             # if the service has been aliased, get the real path ...
98 19 100       26 $path = $self->{service_aliases}->{$path} if exists ${$self->{service_aliases}}{$path};
  19         73  
99             # and go about your normal business ...
100 19         71 my @path = grep { $_ } split /\// => $path;
  56         137  
101 19         40 my $registered_container_name = shift @path;
102 19 100       27 (exists ${$self->{containers}}{$registered_container_name})
  19         78  
103             || throw IOC::ContainerNotFound "There is no registered container found at '$registered_container_name' for the path '${path}'";
104 18         25 my $service;
105 18         26 eval {
106 18         107 $service = $self->{containers}->{$registered_container_name}->find((join "/" => @path), \@extra_args);
107             };
108 18 100       1153 throw IOC::ServiceNotFound "There is no service found at the path '${path}'" => $@ if $@;
109 17         75 return $service;
110             }
111              
112             sub locateContainer {
113 9     9 1 1069 my ($self, $path) = @_;
114 9 100       42 (defined($path)) || throw IOC::InsufficientArguments "You must supply a path to a container";
115 8         31 my @path = grep { $_ } split /\// => $path;
  16         44  
116 8         18 my $registered_container_name = shift @path;
117 8 100       12 (exists ${$self->{containers}}{$registered_container_name})
  8         39  
118             || throw IOC::ContainerNotFound "There is no container found at the path '${path}'";
119 7         19 my $current = $self->{containers}->{$registered_container_name};
120 7         8 eval {
121 7         35 $current = $current->getSubContainer(shift @path) while @path;
122             };
123 7 100       656 throw IOC::ContainerNotFound "There is no container found at the path '${path}'" => $@ if $@;
124             # otherwise ...
125 6         31 return $current;
126             }
127              
128             # searching for containers
129              
130             sub searchForContainer {
131 2     2 1 2116 my ($self, $container_to_find) = @_;
132 2         3 my $container_found;
133 2         2 foreach my $container (values %{$self->{containers}}) {
  2         9  
134 6         26 $container_found = $container->accept(IOC::Visitor::SearchForContainer->new($container_to_find));
135 6 100       27 last if defined $container_found;
136             }
137 2         6 return $container_found;
138             }
139              
140             sub searchForService {
141 2     2 1 965 my ($self, $service_to_find) = @_;
142 2         4 my $service;
143 2         2 foreach my $container (values %{$self->{containers}}) {
  2         8  
144 6         38 $service = $container->accept(IOC::Visitor::SearchForService->new($service_to_find));
145 6 100       36 last if $service;
146             }
147 2         6 return $service;
148             }
149              
150             sub DESTROY {
151 54     54   27254 my ($self) = @_;
152             # get rid of all our containers
153 54         81 foreach my $container (values %{$self->{containers}}) {
  54         678  
154 48 50       11925 defined $container && $container->DESTROY;
155             }
156             # let the Singleton do its work
157 54         301 $self->SUPER::DESTROY();
158             }
159              
160             1;
161              
162             __END__