MooseX-DIC
view release on metacpan or search on metacpan
lib/MooseX/DIC/Container/DefaultImpl.pm view on Meta::CPAN
package MooseX::DIC::Container::DefaultImpl;
use MooseX::DIC::Types;
use aliased 'MooseX::DIC::UnregisteredServiceException';
use aliased 'MooseX::DIC::ServiceRegistry';
use aliased 'MooseX::DIC::PackageNotFoundException';
use aliased 'MooseX::DIC::ContainerException';
use MooseX::DIC::ServiceFactoryFactory 'build_factory';
use Module::Load;
use Try::Tiny;
use Moose;
with 'MooseX::DIC::Container';
with 'MooseX::DIC::Loggable';
has environment => ( is => 'ro', isa => 'Str', default => 'default' );
has registry => (is => 'ro', isa => 'MooseX::DIC::ServiceRegistry', required => 1);
has singletons => (is => 'ro', isa => 'HashRef[HashRef[Any]]', default => sub { { default => {} } });
has service_factories => ( is => 'ro', isa => 'HashRef[ServiceFactory]', default => sub { {} } );
sub has_service {
my ( $self, $interface_name ) = @_;
return $self->registry->has_service($interface_name);
}
sub build_class {
my ($self,$package_name) = @_;
$self->logger->debug("I'm going to build an instance of $package_name");
my $dependencies = $self->get_package_dependencies($package_name);
my $instance =
try { $package_name->new(%$dependencies) }
catch {
my $error = "Could not create an instance for package $package_name via "
."Moose constructor: $_";
$self->logger->error($error);
ContainerException->throw(message => $error);
};
return $instance;
}
sub get_service {
my ( $self, $package_name,$original_environment ) = @_;
my $environment = $original_environment || $self->environment;
# Check it is a registered service
my $meta = $self->registry->get_service_definition($package_name,$environment);
UnregisteredServiceException->throw( service => $package_name )
unless $meta;
my $service;
# If it is a singleton, there's a chance it has already been built
if ( $meta->scope eq 'singleton' ) {
# First retrieve it from the environment, then from default environment
$service = $self->singletons->{ $meta->environment }->{$package_name};
$service = $self->singletons->{'default'}->{$package_name}
unless $service;
}
return $service if $service;
# If the service hasn't been built yet, use the builder class to do it
my $service_factory = $self->_get_service_factory( $meta->builder );
$service = $service_factory->build_service($meta);
# Cache the service if it's a singleton
if ( $meta->scope eq 'singleton' ) {
$self->singletons->{ $meta->environment }->{$package_name} = $service;
}
return $service;
}
sub get_service_metadata {
( run in 0.848 second using v1.01-cache-2.11-cpan-39bf76dae61 )