diff lib/IMPL/Config/Container.pm @ 420:df591e3afd10 ref20150831

sync
author cin
date Sat, 25 Feb 2017 22:35:26 +0300
parents bbc4739c4d48
children 7798345304bc
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__