Mercurial > pub > Impl
diff 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 diff
--- a/lib/IMPL/Config/ActivationContext.pm Sun Jul 16 22:59:39 2017 +0300 +++ b/lib/IMPL/Config/ActivationContext.pm Sun Aug 20 00:20:41 2017 +0300 @@ -1,21 +1,23 @@ package IMPL::Config::ActivationContext; use IMPL::lang qw(:base); -use IMPL::Const qw(:prop); use IMPL::Exception(); use IMPL::declare { require => { - Bag => 'IMPL::Config::ServicesBag', + Bag => 'IMPL::Config::Bag', ServiceNotFoundException => 'IMPL::Config::ServiceNotFoundException', + Descriptor => '-IMPL::Config::Descriptor' }, base => { 'IMPL::Object' => '@_' }, props => [ - container => PROP_RW, - instances => PROP_RW, - _services => PROP_RW, - _stack => PROP_RW + container => 'rw', + owner => 'rw', + instances => 'rw', + name => 'rw', + _services => 'rw', + _stack => 'rw' ] }; @@ -24,15 +26,23 @@ $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 ) = @_; + my ( $this, $name, $services, $container ) = @_; + + my $info = { name => $this->name }; - my $info = { name => $name }; + $this->name($name); + + if ( $container && $this->container != $container ) { + $info->{container} = $this->container; + $this->container($container); + } if ($services) { die IMPL::InvalidArgumentException->new( @@ -42,12 +52,11 @@ my $bag = $this->container->serviceCache->{ ref($services) }; unless ($bag) { - my $container = $this->container; $bag = Bag->new( $this->_services ); + $bag->tag( $container || $this->container ); - # - $bag->Register( - $container->GetLinearRoleHash( $_->{role}, $_->{descriptor} ) ) + $bag->Register( $container->GetLinearRoleHash( $_->{role} ), + $_->{descriptor} ) foreach @$services; $container->serviceCache->{ ref($services) } = $bag; @@ -66,30 +75,45 @@ my $info = pop @{ $this->_stack } or die IMPL::InvalidOperationException->new(); - $this->_services( $info->{services} ) if $info->{services}; + $this->name( $info->{name} ); + $this->_services( $info->{services} ) if $info->{services}; + $this->conatiner( $info->{container} ) if $info->{container}; } sub Resolve { my ( $this, $role, %opts ) = @_; - my $d = $this->_services->Resolve($role); + #change of the container may occur only due resolution of the dependency + my ( $d, $bag ) = $this->_services->Resolve($role); unless ($d) { - die ServiceNotFoundException->new($role) unless $opts{optional}; + die ServiceNotFoundException->new(serviceName => $role) unless $opts{optional}; return $opts{default}; } else { - return $d->Activate($this); + $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->container ); - + my $clone = SELF->new( $this->owner ); + $clone->name($this->name); + $clone->container( $this->container ); $clone->_services( $this->_services ); - $clone->instances( { %{ $this->instances } } ); + $clone->instances( $this->instances ); $clone->_stack( [ @{ $this->_stack } ] ); return $clone; @@ -110,8 +134,33 @@ =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) +=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