diff lib/IMPL/Config/ServiceDescriptor.pm @ 415:3d24b10dd0d5 ref20150831

working on IMPL::Config::Container
author cin
date Tue, 20 Oct 2015 07:32:55 +0300
parents c6e90e02dd17
children cc2cf8c0edc2
line wrap: on
line diff
--- a/lib/IMPL/Config/ServiceDescriptor.pm	Fri Oct 02 06:56:24 2015 +0300
+++ b/lib/IMPL/Config/ServiceDescriptor.pm	Tue Oct 20 07:32:55 2015 +0300
@@ -0,0 +1,95 @@
+package IMPL::Config::ServiceDescriptor;
+use strict;
+
+use IMPL::lang qw(:base);
+use IMPL::Exception();
+use IMPL::declare {
+	require => {
+		Bag => 'IMPL::Config::Bag'
+	},
+	base => [
+		'IMPL::Object'             => undef,
+		'IMPL::Config::Descriptor' => undef
+	],
+	props => [
+		type       => 'ro',
+		activation => 'ro',
+		args       => 'ro',
+		services   => 'ro',
+		_name      => 'rw',
+		_loaded    => 'rw'
+	]
+};
+
+sub CTOR {
+	my ( $this, %opts ) = @_;
+
+	$this->type( $opts{type} )
+	  or die IMPL::InvalidArgumentException->new('type');
+
+	$this->activation(
+		IMPL::Config::Descriptor::ParseActivation( $opts{activation} ) );
+	$this->args( $opts{args} )         if exists $opts{args};
+	$this->services( $opts{services} ) if exists $opts{services};
+
+	$this->_name( 'new {'
+		  . IMPL::Config::Descriptor::ActivationToString( $this->activation )
+		  . '} '
+		  . $this->type );
+}
+
+sub Activate {
+	my ( $this, $context ) = @_;
+
+	$context->EnterScope( $this->_name, $this->services );
+
+	my $activation = $this->activation;
+	my $cache;
+
+	if ( $activation == IMPL::Config::Descriptor::ACTIVATE_SINGLETON ) {
+		$cache = $context->container->root->instances;
+	}
+	elsif ( $activation == IMPL::Config::Descriptor::ACTIVATE_CONTAINER ) {
+		$cache = $context->container->instances;
+	}
+	elsif ( $activation == IMPL::Config::Descriptor::ACTIVATE_CONTEXT ) {
+		$cache = $context->instances;
+	}
+
+	my $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 = $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;