Mercurial > pub > Impl
view lib/IMPL/Config/ActivationContext.pm @ 422:b0481c071bea ref20150831
IMPL::Config::Container tests, YAMLConfiguration now works and tested
author | cin |
---|---|
date | Sun, 20 Aug 2017 00:20:41 +0300 |
parents | 7798345304bc |
children |
line wrap: on
line source
package IMPL::Config::ActivationContext; use IMPL::lang qw(:base); use IMPL::Exception(); use IMPL::declare { require => { Bag => 'IMPL::Config::Bag', ServiceNotFoundException => 'IMPL::Config::ServiceNotFoundException', Descriptor => '-IMPL::Config::Descriptor' }, base => { 'IMPL::Object' => '@_' }, props => [ container => 'rw', owner => 'rw', instances => 'rw', name => 'rw', _services => 'rw', _stack => 'rw' ] }; sub CTOR { my ( $this, $container ) = @_; $this->container($container) or die IMPL::InvalidArgumentException->new('container'); $this->owner($container); $this->_services( $container->services ); $this->instances( {} ); $this->_stack( [] ); } sub EnterScope { my ( $this, $name, $services, $container ) = @_; my $info = { name => $this->name }; $this->name($name); if ( $container && $this->container != $container ) { $info->{container} = $this->container; $this->container($container); } if ($services) { die IMPL::InvalidArgumentException->new( services => 'An array is required' ) unless isarray($services); my $bag = $this->container->serviceCache->{ ref($services) }; unless ($bag) { $bag = Bag->new( $this->_services ); $bag->tag( $container || $this->container ); $bag->Register( $container->GetLinearRoleHash( $_->{role} ), $_->{descriptor} ) foreach @$services; $container->serviceCache->{ ref($services) } = $bag; } $info->{services} = $this->_services; $this->_services($bag); } push @{ $this->_stack }, $info; } sub LeaveScope { my ($this) = @_; my $info = pop @{ $this->_stack } or die IMPL::InvalidOperationException->new(); $this->name( $info->{name} ); $this->_services( $info->{services} ) if $info->{services}; $this->conatiner( $info->{container} ) if $info->{container}; } sub Resolve { my ( $this, $role, %opts ) = @_; #change of the container may occur only due resolution of the dependency my ( $d, $bag ) = $this->_services->Resolve($role); unless ($d) { die ServiceNotFoundException->new(serviceName => $role) unless $opts{optional}; return $opts{default}; } else { $this->EnterScope( $d->GetName(), $d->services(), $bag->tag() ); my $instance = $d->Activate($this); $this->LeaveScope(); return $instance; } } sub Activate { my ( $this, $d ) = @_; $this->EnterScope( $d->GetName(), $d->services() ); my $instance = $d->Activate($this); $this->LeaveScope(); return $instance; } sub Clone { my ($this) = @_; my $clone = SELF->new( $this->owner ); $clone->name($this->name); $clone->container( $this->container ); $clone->_services( $this->_services ); $clone->instances( $this->instances ); $clone->_stack( [ @{ $this->_stack } ] ); return $clone; } 1; __END__ =pod =head1 NAME C<IMPL::Config::ActivationContext> - an activation context for the service =head1 SYNOPSIS For the internal use only =head1 MEMBERS =head2 PROPERTIES =head3 [get] container Current container for the activation context, this container changes during resolution process to match the one in which the resulting descriptor were defined. Descriptors can use this property to access the cache of theirs container. =head3 [get] owner The container which created this context. Descriptors can use this property during theirs activation. =head3 [get] instances The activation cache which can be used to store instances during single resolution process. =head2 METHODS =head3 Resolve($serviceId): $instance Activates and returns an instance specified by C<$serviceId> =head3 Activate($descriptor): $instance Activates and returns an instance of the services for the specified descriptor/ =cut