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 )