view lib/IMPL/Config/ServiceDescriptor.pm @ 420:df591e3afd10 ref20150831

sync
author cin
date Sat, 25 Feb 2017 22:35:26 +0300
parents 3ed0c58e9da3
children 7798345304bc
line wrap: on
line source

package IMPL::Config::ServiceDescriptor;
use strict;

use IMPL::lang qw(:base);
use IMPL::Exception();
use IMPL::declare {
	require => {
		Bag                 => 'IMPL::Config::Bag',
		ActivationException => 'IMPL::Config::ActivationException'
	},
	base => [
		'IMPL::Object'             => undef,
		'IMPL::Config::Descriptor' => undef
	],
	props => [
		type       => 'r',
		activation => 'r',
		args       => 'r',
		services   => 'r',
		norequire  => 'r',
		owner      => 'r',
		_name      => 'rw',
		_loaded    => 'rw'
	]
};

sub CTOR {
	my ( $this, %opts ) = @_;

	$this->type( $opts{type} )
	  or die IMPL::InvalidArgumentException->new('type');
	$this->owner( $opts{owner} )
	  or die IMPL::InvalidArgumentException->new('owner');

	$this->activation( SELF->ParseActivation( $opts{activation} ) );
	$this->args( $opts{args} )           if exists $opts{args};
	$this->services( $opts{services} )   if exists $opts{services};
	$this->norequire( $opts{norequire} ) if exists $opts{norequire};

	$this->_name( 'new {'
		  . SELF->ActivationToString( $this->activation )
		  . '} '
		  . $this->type );
}

sub Activate {
	my ( $this, $context ) = @_;

	my $instance;
	$context->EnterScope( $this->_name, $this->services );

	my $activation = $this->activation;
	my $cache;

	if ( $activation == SELF->ACTIVATE_SINGLETON ) {
		$cache = $context->container->root->instances;
	}
	elsif ( $activation == SELF->ACTIVATE_CONTAINER ) {
		$cache = $this->owner->instances;
	}
	elsif ( $activation == SELF->ACTIVATE_HIERARCHY ) {
		$cache = $context->container->instances;
	}
	elsif ( $activation == SELF->ACTIVATE_CONTEXT ) {
		$cache = $context->instances;
	}

	$instance = $cache->{ ref($this) } if $cache;
	unless ($instance) {
		$instance = $this->CreateInstance($context);
	}

	$cache->{ ref($this) } = $instance if $cache;

	$context->LeaveScope();

	return $instance;
}

sub CreateInstance {
	my ( $this, $context ) = @_;

	my $class =
	    $this->norequire
	  ? $this->type
	  : $context->container->Require( $this->type );

	my $args = $this->args ? $this->args->Activate($context) : undef;

	if ( defined $args ) {
		if ( isarray($args) ) {
			return $class->new(@$args);
		}
		elsif ( ishash($args) ) {
			return $class->new(%$args);
		}
		else {
			return $class->new($args);
		}
	}
	else {
		return $class->new();
	}
}

1;