File Coverage

lib/MooseX/DIC/Container/DefaultImpl.pm
Criterion Covered Total %
statement 68 77 88.3
branch 16 22 72.7
condition 1 3 33.3
subroutine 17 18 94.4
pod 0 4 0.0
total 102 124 82.2


line stmt bran cond sub pod time code
1             package MooseX::DIC::Container::DefaultImpl;
2              
3 5     5   3705 use MooseX::DIC::Types;
  5         19  
  5         191  
4 5     5   39 use aliased 'MooseX::DIC::UnregisteredServiceException';
  5         13  
  5         47  
5 5     5   689 use aliased 'MooseX::DIC::ServiceRegistry';
  5         15  
  5         39  
6 5     5   629 use aliased 'MooseX::DIC::PackageNotFoundException';
  5         12  
  5         29  
7 5     5   622 use aliased 'MooseX::DIC::ContainerException';
  5         14  
  5         30  
8 5     5   3264 use MooseX::DIC::ServiceFactoryFactory 'build_factory';
  5         19  
  5         526  
9 5     5   41 use Module::Load;
  5         12  
  5         25  
10 5     5   260 use Try::Tiny;
  5         13  
  5         258  
11              
12 5     5   38 use Moose;
  5         14  
  5         38  
13             with 'MooseX::DIC::Container';
14             with 'MooseX::DIC::Loggable';
15              
16             has environment => ( is => 'ro', isa => 'Str', default => 'default' );
17             has registry => (is => 'ro', isa => 'MooseX::DIC::ServiceRegistry', required => 1);
18             has singletons => (is => 'ro', isa => 'HashRef[HashRef[Any]]', default => sub { { default => {} } });
19             has service_factories => ( is => 'ro', isa => 'HashRef[ServiceFactory]', default => sub { {} } );
20              
21             sub has_service {
22 6     6 0 25 my ( $self, $interface_name ) = @_;
23              
24 6         265 return $self->registry->has_service($interface_name);
25             }
26              
27             sub build_class {
28 4     4 0 9993 my ($self,$package_name) = @_;
29              
30 4         146 $self->logger->debug("I'm going to build an instance of $package_name");
31             try {
32 4     4   169 load $package_name;
33             } catch {
34 1     1   536 $self->logger->debug("The instance could not be built for $package_name".
35             " because the package could not be found: $_");
36 1         24 PackageNotFoundException->throw(package_name=>$package_name);
37 4         58 };
38              
39 3 100       14702 ContainerException->throw(message => "The package $package_name is not a valid Moose class,"
40             ." it cannot be instantiated") unless $package_name->can('meta');
41              
42 2         7 my %dependencies = ();
43 2         11 foreach my $attribute ($package_name->meta->get_all_attributes){
44             # We can only inject an attribute that defines a constraint
45 4 50       238 if($attribute->type_constraint){
46 4         170 my $service_type = $attribute->type_constraint->name;
47 4         174 my $service = $self->get_service($service_type);
48              
49 4 50       14 unless($service) {
50 0         0 $self->logger->error("Could not find service $service_type for mandatory attribute "
51             .$attribute->name
52             ." while building class $package_name");
53 0 0       0 UnregisteredServiceException->throw(service=>$service_type) if($attribute->is_required);
54             }
55 4         22 $dependencies{$attribute->name} = $service;
56             } else {
57 0 0       0 if($attribute->is_required) {
58 0         0 my $error = "Could not inject the required attribute "
59             .$attribute->name
60             ." of the class $package_name because it has no type constraint";
61 0         0 $self->logger->error($error);
62              
63 0         0 ContainerException->throw(message => $error);
64             }
65             }
66             }
67            
68             my $instance =
69 2     2   117 try { $package_name->new(%dependencies) }
70             catch {
71 0     0   0 my $error = "Could not create an instance for package $package_name via "
72             ."Moose constructor: $_";
73 0         0 $self->logger->error($error);
74 0         0 ContainerException->throw(message => $error);
75 2         21 };
76            
77 2         2671 return $package_name->new(%dependencies);
78             }
79              
80             sub get_service {
81 34     34 0 26707 my ( $self, $package_name,$original_environment ) = @_;
82 34   33     1661 my $environment = $original_environment || $self->environment;
83              
84             # Check it is a registered service
85 34         1430 my $meta = $self->registry->get_service_definition($package_name,$environment);
86 34 100       137 UnregisteredServiceException->throw( service => $package_name )
87             unless $meta;
88              
89 33         71 my $service;
90              
91             # If it is a singleton, there's a chance it has already been built
92 33 100       1490 if ( $meta->scope eq 'singleton' ) {
93              
94             # First retrieve it from the environment, then from default environment
95 26         1042 $service = $self->singletons->{ $meta->environment }->{$package_name};
96 26 100       730 $service = $self->singletons->{'default'}->{$package_name}
97             unless $service;
98             }
99 33 100       256 return $service if $service;
100              
101             # If the service hasn't been built yet, use the builder class to do it
102 23         1025 my $service_factory = $self->_get_service_factory( $meta->builder );
103 23         123 $service = $service_factory->build_service($meta);
104              
105             # Cache the service if it's a singleton
106 22 100       1133 if ( $meta->scope eq 'singleton' ) {
107 15         677 $self->singletons->{ $meta->environment }->{$package_name} = $service;
108             }
109              
110 22         184 return $service;
111             }
112              
113             sub get_service_metadata {
114 3     3 0 13 my ($self,$interface_name,$environment) = @_;
115              
116 3         143 return $self->registry->get_service_definition($interface_name,$environment);
117             }
118              
119             sub _get_service_factory {
120 23     23   77 my ( $self, $factory_type ) = @_;
121              
122 23         988 my $service_factory = $self->service_factories->{$factory_type};
123 23 100       84 unless ($service_factory) {
124 9         92 $service_factory = build_factory( $factory_type, $self );
125 9         467 $self->service_factories->{$factory_type} = $service_factory;
126             }
127              
128 23         78 return $service_factory;
129             }
130              
131             1;