Mercurial > pub > Impl
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;