File Coverage

blib/lib/Syringe.pm
Criterion Covered Total %
statement 6 6 100.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 8 8 100.0


line stmt bran cond sub pod time code
1             package Syringe;
2              
3 1     1   33395 use 5.6.1;
  1         5  
  1         50  
4              
5 1     1   6 use base 'Class::Singleton';
  1         1  
  1         816  
6             our $VERSION = '0.01';
7              
8             use Modern::Perl;
9             use Data::Dumper;
10             use Log::Log4perl qw(:easy);
11             use YAML::XS qw(LoadFile);
12             use Carp;
13             use Scalar::Util qw(blessed);
14              
15             use Log::Log4perl qw(get_logger);
16              
17             my $default_log4perl_conf = q(
18             log4perl.rootLogger=DEBUG,Logfile
19             log4perl.category.default=WARN,Logfile
20             log4perl.appender.Logfile=Log::Log4perl::Appender::File
21             log4perl.appender.Logfile.filename=test.log
22             log4perl.appender.Logfile.layout=Log::Log4perl::Layout::PatternLayout
23             log4perl.appender.Logfile.layout.ConversionPattern=%d %M %m %n
24             );
25              
26             #-------------------------------------------------------------------------------
27              
28              
29             # this only gets called the first time instance() is called
30             sub _new_instance {
31             my ($proto, %params) = @_;
32              
33             my $class = ref $proto || $proto;
34              
35             if ($params{log4perlconf}) {
36             Log::Log4perl::init($params{log4perlconf});
37             } else {
38             Log::Log4perl::init(\$default_log4perl_conf);
39             }
40              
41             $params{logger} = get_logger();
42              
43             $params{logger}->info("_new_instance called");
44              
45             my $self = bless \%params, $class;
46              
47             $params{config} = LoadFile($self->{path});
48              
49             $self->_compile;
50              
51             return $self;
52             }
53              
54             #-------------------------------------------------------------------------------
55              
56             sub logger {
57             my $self = shift;
58             return $self->{logger};
59             }
60              
61             #-------------------------------------------------------------------------------
62              
63             sub _config {
64             my $self = shift;
65             return $self->{config};
66             }
67              
68             #-------------------------------------------------------------------------------
69              
70             sub _instantiate {
71             my ($self, $config, $service) = @_;
72              
73             $self->logger->info("Start instantiation of $service");
74              
75             my $class = $config->{$service}->{class}->{name};
76            
77             my $dependencies = $config->{$service}->{'dependencies'};
78              
79             my %args;
80              
81             for my $dependency_name ( keys %{ $dependencies } ) {
82             $self->logger->info("Parsing dependency [$dependency_name]");
83             my $value;
84             my $dep_service = $dependencies->{$dependency_name}->{'service'};
85             my $dep_value = $dependencies->{$dependency_name}->{'value'};
86             my $is_service = defined $dep_service ? 1 : 0;
87              
88             # look for services first
89             if ($is_service) {
90             $self->logger->info("[$dependency_name] is service.");
91              
92             # check to see if it was loaded into runtime yet
93             if (exists $config->{$dep_service}->{'object'}) {
94             # set the value to the object in memory
95             $value = $config->{$dep_service}->{'object'};
96             }
97             else {
98             # recursive call
99             $self->logger->info("[$dependency_name] is not existing service.");
100             $value = $self->_instantiate($config, $dep_service);
101             }
102             } elsif (!$is_service) {
103             $self->logger->info("[$dependency_name] is a value.");
104             $value = $dep_value;
105             }
106            
107             $args{$dependency_name} = $value;
108             }
109            
110             my $constructor = $config->{$service}->{class}->{constructor} || 'new';
111              
112             # instantiate new object
113            
114             if ($self->logger->is_debug) {
115             for my $lib (@INC) {
116             $self->logger->debug("\@INC contains [ $lib ]");
117             }
118             }
119              
120             eval "require $class";
121             eval "import $class";
122              
123             my $object = $class->$constructor(%args);
124              
125             if (ref $object eq $class) {
126             $self->logger->info("Succes! instantiated service [$service] class [$class]!");
127             }
128             else {
129             $self->logger->fatal("Failed to instantiate service [$service] class [$class]!");
130             }
131              
132             $config->{$service}->{object} = $object;
133              
134             return $object;
135             }
136              
137             #-------------------------------------------------------------------------------
138              
139             sub _compile {
140             my $self = shift;
141             my $config = $self->_config;
142             for my $service ( sort keys %$config) {
143             $self->logger->info("Found service named [ $service ]!");
144              
145             $self->_instantiate($config, $service);
146             }
147             }
148              
149             #-------------------------------------------------------------------------------
150              
151             sub get_class {
152             my ($self, $service) = @_;
153              
154             $self->logger->debug("called with arg $service");
155              
156             return $self->_config->{$service}->{class}->{name};
157             }
158              
159             #-------------------------------------------------------------------------------
160              
161             sub get_service {
162             my ($self, $service) = @_;
163              
164             $self->logger->debug("called with arg $service");
165              
166             my $config = $self->_config;
167            
168             my $object = $self->_config->{$service}->{'object'};
169             my $ref = ref $object;
170             my $class = $self->get_class($service);
171              
172             $self->logger->debug("Ref of Object returned for $service is $ref");
173              
174             if (ref $object ne $class) {
175             $self->logger->fatal("Object is not a $class!");
176             }
177              
178             return $object;
179             }
180              
181             #-------------------------------------------------------------------------------
182              
183             sub register_service {
184             my ($self, $service_identifier, $service) = @_;
185              
186             $self->logger->info("called with service identifier [$service_identifier]");
187              
188              
189             my $class = blessed $service;
190              
191             if (!$class) {
192             $self->logger->error("Failed to pass an object!");
193             croak("You must pass a blessed object!");
194             }
195              
196             my $config = $self->_config;
197              
198             if (exists $config->{$service_identifier}->{'object'}) {
199             $self->logger->error("Service identifier [$service_identifier] already exists!");
200             croak("You are trying to register a service with an existing name!");
201             }
202              
203             $config->{$service_identifier}->{'class'}->{name} = $class;
204             $config->{$service_identifier}->{'object'} = $service;
205              
206             return 1;
207             }
208              
209             #-------------------------------------------------------------------------------
210              
211             1;
212              
213             __END__