| 407 | 1 package IMPL::Config::Container; | 
| 412 | 2 use strict; | 
|  | 3 | 
| 413 | 4 use IMPL::Exception(); | 
| 412 | 5 use IMPL::lang qw(:base); | 
|  | 6 use IMPL::declare { | 
|  | 7 	require => { | 
| 413 | 8 		Descriptor        => 'IMPL::Config::Descriptor', | 
|  | 9 		ValueDescriptor   => 'IMPL::Config::ValueDescriptor', | 
|  | 10 		ActivationContext => 'IMPL::Config::ActivationContext', | 
|  | 11 		Hierarchy         => 'IMPL::Config::Hierarchy', | 
| 415 | 12 		Bag               => 'IMPL::Config::Bag', | 
|  | 13 		Loader            => 'IMPL::Code::Loader' | 
| 412 | 14 	}, | 
|  | 15 	base => [ | 
|  | 16 		'IMPL::Object' => undef | 
|  | 17 	], | 
|  | 18 	props => [ | 
| 413 | 19 		roles     => 'r', | 
|  | 20 		services  => 'r', | 
|  | 21 		instances => 'r', | 
| 415 | 22 		parent    => 'r', | 
|  | 23 		root      => 'r', | 
|  | 24 		loader    => 'r' | 
| 412 | 25 	] | 
|  | 26 }; | 
|  | 27 | 
|  | 28 my $nextRoleId = 1; | 
|  | 29 | 
| 413 | 30 sub CTOR { | 
| 415 | 31 	my ( $this, $parent, %opts ) = @_; | 
| 413 | 32 | 
|  | 33 	$this->instances( {} ); | 
|  | 34 | 
| 415 | 35 	$this->loader( $opts{loader} || Loader->safe ); | 
|  | 36 | 
| 413 | 37 	if ($parent) { | 
|  | 38 		$this->roles( Hierarchy->new( $parent->roles ) ); | 
|  | 39 		$this->services( Bag->new( $parent->services ) ); | 
|  | 40 		$this->parent($parent); | 
| 415 | 41 		$this->root( $parent->root ); | 
| 413 | 42 	} | 
|  | 43 	else { | 
|  | 44 		$this->roles( Hierarchy->new() ); | 
|  | 45 		$this->services( Bag->new() ); | 
| 415 | 46 		$this->root($this); | 
| 413 | 47 	} | 
|  | 48 } | 
| 412 | 49 | 
| 417 | 50 sub Require { | 
|  | 51 	my ($this, $class) = @_; | 
|  | 52 | 
|  | 53 	return $this->loader->Require($class); | 
|  | 54 } | 
|  | 55 | 
| 412 | 56 sub Register { | 
| 413 | 57 	my ( $this, $role, $service ) = @_; | 
|  | 58 | 
| 415 | 59 	die IMPL::InvalidArgumentException->new('service') | 
|  | 60 	  unless is( $service, Descriptor ); | 
|  | 61 	$this->services->Register( $this->GetLinearRoleHash($role), $service ); | 
|  | 62 } | 
|  | 63 | 
|  | 64 sub GetLinearRoleHash { | 
|  | 65 	my ( $this, $role ) = @_; | 
|  | 66 | 
| 413 | 67 	die IMPL::InvalidArgumentException->new( | 
|  | 68 		role => 'The argument is required' ) | 
|  | 69 	  unless $role; | 
|  | 70 | 
|  | 71 	if ( isarray($role) ) { | 
|  | 72 		my $tempRole = "unnamed-" . $nextRoleId++; | 
| 417 | 73 		$this->roles->AddRole( $tempRole, $role ); | 
| 413 | 74 		$role = $tempRole; | 
| 412 | 75 	} | 
| 413 | 76 | 
| 415 | 77 	$this->roles->GetLinearRoleHash($role); | 
| 413 | 78 } | 
|  | 79 | 
|  | 80 sub Resolve { | 
|  | 81 	my ( $this, $role, %opts ) = @_; | 
|  | 82 | 
|  | 83 	my $descriptor = $this->services->Resolve($role); | 
|  | 84 | 
|  | 85 	return $descriptor->Activate( ActivationContext->new($this) ) | 
| 417 | 86 	  if $descriptor; | 
| 413 | 87 | 
|  | 88 	return $opts{default} if exists $opts{default}; | 
|  | 89 } | 
|  | 90 | 
|  | 91 sub ResolveAll { | 
|  | 92 	my ( $this, $role, %opts ) = @_; | 
|  | 93 | 
|  | 94 	my $all = $this->services->ResolveAll($role); | 
|  | 95 | 
|  | 96 	my $context; | 
|  | 97 | 
|  | 98 	my @result; | 
|  | 99 | 
|  | 100 	foreach my $service (@$all) { | 
|  | 101 		$context = ActivationContext->new($this) | 
|  | 102 		  unless $context || $opts{shared}; | 
|  | 103 | 
|  | 104 		push @result, $service->Activate($context); | 
|  | 105 	} | 
|  | 106 | 
|  | 107 	return \@result; | 
| 412 | 108 } | 
| 407 | 109 | 
|  | 110 1; | 
|  | 111 | 
|  | 112 __END__ | 
|  | 113 | 
|  | 114 =pod | 
|  | 115 | 
|  | 116 =head1 NAME | 
|  | 117 | 
|  | 118 C<IMPL::Config::Container> - dependency injection container | 
|  | 119 | 
|  | 120 =head1 SYNOPSIS | 
|  | 121 | 
|  | 122 =head2 METHODS | 
|  | 123 | 
| 415 | 124 =head3 Resolve($role) | 
| 407 | 125 | 
| 415 | 126 =head3 ResolveAll($role, shared => $useSharedContext) | 
| 407 | 127 | 
| 415 | 128 =head3 Register($role, $service) | 
| 407 | 129 | 
| 412 | 130 =cut |