Mercurial > pub > Impl
diff lib/IMPL/Config/ActivationContext.pm @ 416:cc2cf8c0edc2 ref20150831
sync
author | cin |
---|---|
date | Thu, 29 Oct 2015 03:50:25 +0300 |
parents | 3d24b10dd0d5 |
children | 3ed0c58e9da3 |
line wrap: on
line diff
--- a/lib/IMPL/Config/ActivationContext.pm Tue Oct 20 07:32:55 2015 +0300 +++ b/lib/IMPL/Config/ActivationContext.pm Thu Oct 29 03:50:25 2015 +0300 @@ -1,10 +1,12 @@ package IMPL::Config::ActivationContext; +use IMPL::lang qw(:base); use IMPL::Const qw(:prop); use IMPL::Exception(); use IMPL::declare { require => { - PropertyBag => 'IMPL::Config::ServicesBag' + Bag => 'IMPL::Config::ServicesBag', + ServiceNotFoundException => 'IMPL::Config::ServiceNotFoundException', }, base => { 'IMPL::Object' => '@_' @@ -21,7 +23,9 @@ my ( $this, $container ) = @_; $this->container($container) - or die IMPL::InvalidArgumentException('container'); + or die IMPL::InvalidArgumentException->new('container'); + $this->_cache({}); + $this->_stack([]); } sub EnterScope { @@ -30,29 +34,67 @@ my $info = { name => $name }; if ($services) { - $info->{services} = $this->_services; + die IMPL::InvalidArgumentException->new( + services => 'An array is required' ) + unless isarray($services); + + my $bag = $this->container->serviceCache->{ ref($services) }; + + unless ($bag) { + my $container = $this->container; + $bag = Bag->new( $this->_services ); - $this->_services( $services ); + $bag->Register( + $container->GetLinearRoleHash( $_->{role}, $_->{descriptor} ) ) + foreach @$services; + + $container->serviceCache->{ ref($services) } = $bag; + } + + $info->{services} = $this->_services; + $this->_services($bag); } - $this->_stack->Push($info); + push @{$this->_stack}, $info; } sub LeaveScope { my ($this) = @_; - my $info = $this->_stack->Pop() - or die IMPL::InvalidOperationException(); + my $info = pop @{$this->_stack} + or die IMPL::InvalidOperationException->new(); + + $this->_services( $info->{services} ) if $info->{services}; +} - if ( $info->{services} ) $this->_services( $info->{services} ); +sub GuardScope { + my ( $this, $name, $services, $action ) = @_; + + $this->EnterScope( $name, $service ); + eval { $action ($this) if $action; } my $err = $@; + $this->LeaveScope(); + die $err if $err; } sub Resolve { - my ($this, $role, %opts) = @_; + my ( $this, $role, %opts ) = @_; + + my $d = $this->_services->Reolve($role); + + unless($d) { + die ServiceNotFoundException->new($role) unless $opts{optional}; + return $opts{default}; + } else { + return $d->Activate($this); + } } sub Clone { my ($this) = @_; + + my $clone = SELF->new($this->container); + + $clone->_ } 1; @@ -72,6 +114,6 @@ =head2 METHODS -=head3 GetService($serviceId) +=head3 Resolve($serviceId) =cut