# HG changeset patch # User cin # Date 1488051326 -10800 # Node ID df591e3afd10dfb4f173e347dc173e6c697a8397 # Parent bbc4739c4d483a79e9ecc4e53b67523c2ae24004 sync diff -r bbc4739c4d48 -r df591e3afd10 lib/IMPL/Config/Container.pm --- 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__ diff -r bbc4739c4d48 -r df591e3afd10 lib/IMPL/Config/Descriptor.pm --- 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); diff -r bbc4739c4d48 -r df591e3afd10 lib/IMPL/Config/ServiceDescriptor.pm --- 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; }