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