changeset 420:df591e3afd10 ref20150831

sync
author cin
date Sat, 25 Feb 2017 22:35:26 +0300
parents bbc4739c4d48
children 7798345304bc
files lib/IMPL/Config/Container.pm lib/IMPL/Config/Descriptor.pm lib/IMPL/Config/ServiceDescriptor.pm
diffstat 3 files changed, 93 insertions(+), 73 deletions(-) [+]
line wrap: on
line diff
--- a/lib/IMPL/Config/Container.pm	Sun Jan 29 10:30:20 2017 +0300
+++ b/lib/IMPL/Config/Container.pm	Sat Feb 25 22:35:26 2017 +0300
@@ -1,112 +1,124 @@
 package IMPL::Config::Container;
 use strict;
 
+use Scalar::Util qw(blessed);
 use IMPL::Exception();
 use IMPL::lang qw(:base);
 use IMPL::declare {
-	require => {
-		Descriptor        => 'IMPL::Config::Descriptor',
-		ActivationContext => 'IMPL::Config::ActivationContext',
-		Hierarchy         => 'IMPL::Config::Hierarchy',
-		Bag               => 'IMPL::Config::Bag',
-		Loader            => 'IMPL::Code::Loader'
-	},
-	base => [
-		'IMPL::Object' => undef
-	],
-	props => [
-		roles     => 'r',
-		services  => 'r',
-		instances => 'r',
-		parent    => 'r',
-		root      => 'r',
-		loader    => 'r'
-	]
+    require => {
+        Descriptor        => 'IMPL::Config::Descriptor',
+        ActivationContext => 'IMPL::Config::ActivationContext',
+        Hierarchy         => 'IMPL::Config::Hierarchy',
+        Bag               => 'IMPL::Config::Bag',
+        Loader            => 'IMPL::Code::Loader'
+    },
+    base => [
+        'IMPL::Object'             => undef,
+        'IMPL::Object::Disposable' => undef
+    ],
+    props => [
+        roles     => 'r',
+        services  => 'r',
+        instances => 'r',
+        parent    => 'r',
+        root      => 'r',
+        loader    => 'r'
+    ]
 };
 
 my $nextRoleId = 1;
 
 sub CTOR {
-	my ( $this, $parent, %opts ) = @_;
+    my ( $this, $parent, %opts ) = @_;
 
-	$this->instances( {} );
+    $this->instances( {} );
 
-	$this->loader( $opts{loader} || Loader->safe );
+    $this->loader( $opts{loader} || Loader->safe );
 
-	if ($parent) {
-		$this->roles( Hierarchy->new( $parent->roles ) );
-		$this->services( Bag->new( $parent->services ) );
-		$this->parent($parent);
-		$this->root( $parent->root );
-	}
-	else {
-		$this->roles( Hierarchy->new() );
-		$this->services( Bag->new() );
-		$this->root($this);
-	}
+    if ($parent) {
+        $this->roles( Hierarchy->new( $parent->roles ) );
+        $this->services( Bag->new( $parent->services ) );
+        $this->parent($parent);
+        $this->root( $parent->root );
+    }
+    else {
+        $this->roles( Hierarchy->new() );
+        $this->services( Bag->new() );
+        $this->root($this);
+    }
+}
+
+sub Dispose {
+    my ($this) = @_;
+
+    my $d;
+    foreach my $v ( values %{ $this->instances } ) {
+        if ( $d = blessed($v) && $v->can('Dispose') ) {
+            &$d($v);
+        }
+    }
 }
 
 sub Require {
-	my ($this, $class) = @_;
-	
-	return $this->loader->Require($class);
+    my ( $this, $class ) = @_;
+
+    return $this->loader->Require($class);
 }
 
 sub Register {
-	my ( $this, $role, $service ) = @_;
+    my ( $this, $role, $service ) = @_;
 
-	die IMPL::InvalidArgumentException->new('service')
-	  unless is( $service, Descriptor );
-	$this->services->Register( $this->GetLinearRoleHash($role), $service );
+    die IMPL::InvalidArgumentException->new('service')
+      unless is( $service, Descriptor );
+    $this->services->Register( $this->GetLinearRoleHash($role), $service );
 }
 
 sub GetLinearRoleHash {
-	my ( $this, $role ) = @_;
+    my ( $this, $role ) = @_;
 
-	die IMPL::InvalidArgumentException->new(
-		role => 'The argument is required' )
-	  unless $role;
+    die IMPL::InvalidArgumentException->new(
+        role => 'The argument is required' )
+      unless $role;
 
-	if ( isarray($role) ) {
-		my $tempRole = "unnamed-" . $nextRoleId++;
-		$this->roles->AddRole( $tempRole, $role );
-		$role = $tempRole;
-	}
+    if ( isarray($role) ) {
+        my $tempRole = "unnamed-" . $nextRoleId++;
+        $this->roles->AddRole( $tempRole, $role );
+        $role = $tempRole;
+    }
 
-	$this->roles->GetLinearRoleHash($role);
+    $this->roles->GetLinearRoleHash($role);
 }
 
 sub Resolve {
-	my ( $this, $role, %opts ) = @_;
+    my ( $this, $role, %opts ) = @_;
 
-	my $descriptor = $this->services->Resolve($role);
+    my $descriptor = $this->services->Resolve($role);
 
-	return $descriptor->Activate( ActivationContext->new($this) )
-	  if $descriptor;
+    return $descriptor->Activate( ActivationContext->new($this) )
+      if $descriptor;
 
-	return $opts{default} if exists $opts{default};
+    return $opts{default} if exists $opts{default};
 }
 
 sub ResolveAll {
-	my ( $this, $role, %opts ) = @_;
+    my ( $this, $role, %opts ) = @_;
 
-	my $all = $this->services->ResolveAll($role);
+    my $all = $this->services->ResolveAll($role);
 
-	my $context;
+    my $context;
 
-	my @result;
+    my @result;
 
-	foreach my $service (@$all) {
-		$context = ActivationContext->new($this)
-		  unless $context || $opts{shared};
+    foreach my $service (@$all) {
+        $context = ActivationContext->new($this)
+          unless $context || $opts{shared};
 
-		push @result, $service->Activate($context);
-	}
+        push @result, $service->Activate($context);
+    }
 
-	return \@result;
+    return \@result;
 }
 
-
 1;
 
 __END__
--- a/lib/IMPL/Config/Descriptor.pm	Sun Jan 29 10:30:20 2017 +0300
+++ b/lib/IMPL/Config/Descriptor.pm	Sat Feb 25 22:35:26 2017 +0300
@@ -5,12 +5,14 @@
 
 sub ACTIVATE_SINGLETON() { 1 }
 sub ACTIVATE_CONTAINER() { 2 }
-sub ACTIVATE_CONTEXT()   { 3 }
-sub ACTIVATE_CALL()      { 4 }
+sub ACTIVATE_HIERARCHY() { 3 }
+sub ACTIVATE_CONTEXT()   { 4 }
+sub ACTIVATE_CALL()      { 5 }
 
 my %activateNames = (
 	singleton => ACTIVATE_SINGLETON,
 	container => ACTIVATE_CONTAINER,
+	hierarchy => ACTIVATE_HIERARCHY,
 	context   => ACTIVATE_CONTEXT,
 	call      => ACTIVATE_CALL
 );
@@ -30,6 +32,7 @@
 	return grep $_ == $val,
 	  ACTIVATE_SINGLETON,
 	  ACTIVATE_CONTAINER,
+	  ACTIVATE_HIERARCHY,
 	  ACTIVATE_CONTEXT, ACTIVATE_CALL ? $val : ACTIVATE_CALL
 	  if looks_like_number($val);
 
--- a/lib/IMPL/Config/ServiceDescriptor.pm	Sun Jan 29 10:30:20 2017 +0300
+++ b/lib/IMPL/Config/ServiceDescriptor.pm	Sat Feb 25 22:35:26 2017 +0300
@@ -18,6 +18,7 @@
 		args       => 'r',
 		services   => 'r',
 		norequire  => 'r',
+		owner      => 'r',
 		_name      => 'rw',
 		_loaded    => 'rw'
 	]
@@ -28,15 +29,16 @@
 
 	$this->type( $opts{type} )
 	  or die IMPL::InvalidArgumentException->new('type');
+	$this->owner( $opts{owner} )
+	  or die IMPL::InvalidArgumentException->new('owner');
 
-	$this->activation(
-		IMPL::Config::Descriptor::ParseActivation( $opts{activation} ) );
+	$this->activation( SELF->ParseActivation( $opts{activation} ) );
 	$this->args( $opts{args} )           if exists $opts{args};
 	$this->services( $opts{services} )   if exists $opts{services};
 	$this->norequire( $opts{norequire} ) if exists $opts{norequire};
 
 	$this->_name( 'new {'
-		  . IMPL::Config::Descriptor::ActivationToString( $this->activation )
+		  . SELF->ActivationToString( $this->activation )
 		  . '} '
 		  . $this->type );
 }
@@ -50,13 +52,16 @@
 	my $activation = $this->activation;
 	my $cache;
 
-	if ( $activation == IMPL::Config::Descriptor::ACTIVATE_SINGLETON ) {
+	if ( $activation == SELF->ACTIVATE_SINGLETON ) {
 		$cache = $context->container->root->instances;
 	}
-	elsif ( $activation == IMPL::Config::Descriptor::ACTIVATE_CONTAINER ) {
+	elsif ( $activation == SELF->ACTIVATE_CONTAINER ) {
+		$cache = $this->owner->instances;
+	}
+	elsif ( $activation == SELF->ACTIVATE_HIERARCHY ) {
 		$cache = $context->container->instances;
 	}
-	elsif ( $activation == IMPL::Config::Descriptor::ACTIVATE_CONTEXT ) {
+	elsif ( $activation == SELF->ACTIVATE_CONTEXT ) {
 		$cache = $context->instances;
 	}