Mercurial > pub > Impl
view lib/IMPL/Config/Container.pm @ 427:09e0086a82a7 ref20150831 tip
Merge
author | cin |
---|---|
date | Tue, 15 May 2018 00:51:33 +0300 |
parents | b0481c071bea |
children |
line wrap: on
line source
package IMPL::Config::Container; use strict; use mro; 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, 'IMPL::Object::Disposable' => undef ], props => [ roles => 'r', services => 'r', serviceCache => 'r', instances => 'r', parent => 'r', root => 'r', loader => 'r' ] }; my $nextRoleId = 1; sub CTOR { my ( $this, $parent, %opts ) = @_; $this->instances( {} ); $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); } $this->services->tag($this); } sub Dispose { my ($this) = @_; my $d; foreach my $v ( values %{ $this->instances } ) { if ( $d = blessed($v) && $v->can('Dispose') ) { &$d($v); } } $this->next::method(); } sub Require { my ( $this, $class ) = @_; return $this->loader->Require($class); } sub Register { my ( $this, $role, $service ) = @_; die IMPL::InvalidArgumentException->new('service') unless is( $service, Descriptor ); $this->services->Register( $this->GetLinearRoleHash($role), $service ); } sub GetLinearRoleHash { my ( $this, $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; } $this->roles->GetLinearRoleHash($role); } sub Resolve { my ( $this, $role ) = @_; my $descriptor = $this->services->Resolve($role); return ActivationContext->new($this)->Activate($descriptor) if $descriptor; } sub ResolveAll { my ( $this, $role, %opts ) = @_; my $all = $this->services->ResolveAll($role); my $context; my @result; foreach my $service (@$all) { $context = ActivationContext->new($this) unless $context && $opts{shared}; push @result, $context->Activate($service); } return \@result; } 1; __END__ =pod =head1 NAME C<IMPL::Config::Container> - dependency injection container =head1 SYNOPSIS =head2 METHODS =head3 Resolve($role) =head3 ResolveAll($role, shared => $useSharedContext) =head3 Register($role, $service) =cut