diff lib/IMPL/Config/Container.pm @ 413:af8d359ee4cc ref20150831

working on di container
author cin
date Thu, 24 Sep 2015 12:19:30 +0300
parents 30e8c6a74937
children ec6f2d389d1e
line wrap: on
line diff
--- a/lib/IMPL/Config/Container.pm	Mon Sep 21 19:54:10 2015 +0300
+++ b/lib/IMPL/Config/Container.pm	Thu Sep 24 12:19:30 2015 +0300
@@ -1,39 +1,94 @@
 package IMPL::Config::Container;
 use strict;
 
+use IMPL::Exception();
 use IMPL::lang qw(:base);
 use IMPL::declare {
 	require => {
-		Descriptor => 'IMPL::Config::Descriptor'
+		Descriptor        => 'IMPL::Config::Descriptor',
+		ValueDescriptor   => 'IMPL::Config::ValueDescriptor',
+		ActivationContext => 'IMPL::Config::ActivationContext',
+		Hierarchy         => 'IMPL::Config::Hierarchy',
+		Bag               => 'IMPL::Config::Bag'
 	},
 	base => [
 		'IMPL::Object' => undef
 	],
 	props => [
-		roles => 'r',
-		services => 'r',
-		instances => 'r'
+		roles     => 'r',
+		services  => 'r',
+		instances => 'r',
+		parent    => 'r'
 	]
 };
 
 my $nextRoleId = 1;
 
-use IMPL::Exception();
+sub CTOR {
+	my ( $this, $parent ) = @_;
+
+	$this->instances( {} );
+
+	if ($parent) {
+		$this->roles( Hierarchy->new( $parent->roles ) );
+		$this->services( Bag->new( $parent->services ) );
+		$this->parent($parent);
+	}
+	else {
+		$this->roles( Hierarchy->new() );
+		$this->services( Bag->new() );
+	}
+}
 
 sub Register {
-	my ($this, $role, $service) = @_;
-	
-	die IMPL::InvalidArgumentException->new(role => 'The argument is required') unless $role;
-	die IMPL::InvalidArgumentException->new('service') unless is($service, Descriptor);
-	
-	if (isarray($role)) {
-        my $tempRole = "unnamed-" . $nextRoleId++;
-        $this->role->AddRole($tempRole, $role);
-        $role = $tempRole;
+	my ( $this, $role, $service ) = @_;
+
+	die IMPL::InvalidArgumentException->new(
+		role => 'The argument is required' )
+	  unless $role;
+	die IMPL::InvalidArgumentException->new('service')
+	  unless is( $service, Descriptor );
+
+	if ( isarray($role) ) {
+		my $tempRole = "unnamed-" . $nextRoleId++;
+		$this->role->AddRole( $tempRole, $role );
+		$role = $tempRole;
 	}
-	
-	$this->services->Register($role, $service);
-	
+
+	$service = ValueDescriptor->new( value => $service )
+	  unless is( $service, Descriptor );
+
+	$this->services->Register( $role, $this->roles->GetLinearRoleHash($role), $service );
+}
+
+sub Resolve {
+	my ( $this, $role, %opts ) = @_;
+
+	my $descriptor = $this->services->Resolve($role);
+
+	return $descriptor->Activate( ActivationContext->new($this) )
+	  if $descirptor;
+
+	return $opts{default} if exists $opts{default};
+}
+
+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, $service->Activate($context);
+	}
+
+	return \@result;
 }
 
 1;