Mercurial > pub > Impl
annotate lib/IMPL/Config/Container.pm @ 425:c27434cdd611 ref20150831
sync
| author | cin | 
|---|---|
| date | Tue, 03 Apr 2018 19:30:01 +0300 | 
| parents | b0481c071bea | 
| children | 
| rev | line source | 
|---|---|
| 407 | 1 package IMPL::Config::Container; | 
| 412 | 2 use strict; | 
| 
422
 
b0481c071bea
IMPL::Config::Container tests, YAMLConfiguration now works and tested
 
cin 
parents: 
421 
diff
changeset
 | 
3 use mro; | 
| 420 | 4 use Scalar::Util qw(blessed); | 
| 413 | 5 use IMPL::Exception(); | 
| 412 | 6 use IMPL::lang qw(:base); | 
| 7 use IMPL::declare { | |
| 420 | 8 require => { | 
| 9 Descriptor => 'IMPL::Config::Descriptor', | |
| 10 ActivationContext => 'IMPL::Config::ActivationContext', | |
| 11 Hierarchy => 'IMPL::Config::Hierarchy', | |
| 12 Bag => 'IMPL::Config::Bag', | |
| 13 Loader => 'IMPL::Code::Loader' | |
| 14 }, | |
| 15 base => [ | |
| 16 'IMPL::Object' => undef, | |
| 17 'IMPL::Object::Disposable' => undef | |
| 18 ], | |
| 19 props => [ | |
| 
422
 
b0481c071bea
IMPL::Config::Container tests, YAMLConfiguration now works and tested
 
cin 
parents: 
421 
diff
changeset
 | 
20 roles => 'r', | 
| 
 
b0481c071bea
IMPL::Config::Container tests, YAMLConfiguration now works and tested
 
cin 
parents: 
421 
diff
changeset
 | 
21 services => 'r', | 
| 
 
b0481c071bea
IMPL::Config::Container tests, YAMLConfiguration now works and tested
 
cin 
parents: 
421 
diff
changeset
 | 
22 serviceCache => 'r', | 
| 
 
b0481c071bea
IMPL::Config::Container tests, YAMLConfiguration now works and tested
 
cin 
parents: 
421 
diff
changeset
 | 
23 instances => 'r', | 
| 
 
b0481c071bea
IMPL::Config::Container tests, YAMLConfiguration now works and tested
 
cin 
parents: 
421 
diff
changeset
 | 
24 parent => 'r', | 
| 
 
b0481c071bea
IMPL::Config::Container tests, YAMLConfiguration now works and tested
 
cin 
parents: 
421 
diff
changeset
 | 
25 root => 'r', | 
| 
 
b0481c071bea
IMPL::Config::Container tests, YAMLConfiguration now works and tested
 
cin 
parents: 
421 
diff
changeset
 | 
26 loader => 'r' | 
| 420 | 27 ] | 
| 412 | 28 }; | 
| 29 | |
| 30 my $nextRoleId = 1; | |
| 31 | |
| 413 | 32 sub CTOR { | 
| 420 | 33 my ( $this, $parent, %opts ) = @_; | 
| 413 | 34 | 
| 420 | 35 $this->instances( {} ); | 
| 413 | 36 | 
| 420 | 37 $this->loader( $opts{loader} || Loader->safe ); | 
| 415 | 38 | 
| 420 | 39 if ($parent) { | 
| 40 $this->roles( Hierarchy->new( $parent->roles ) ); | |
| 41 $this->services( Bag->new( $parent->services ) ); | |
| 42 $this->parent($parent); | |
| 43 $this->root( $parent->root ); | |
| 44 } | |
| 45 else { | |
| 46 $this->roles( Hierarchy->new() ); | |
| 47 $this->services( Bag->new() ); | |
| 48 $this->root($this); | |
| 49 } | |
| 
422
 
b0481c071bea
IMPL::Config::Container tests, YAMLConfiguration now works and tested
 
cin 
parents: 
421 
diff
changeset
 | 
50 | 
| 
 
b0481c071bea
IMPL::Config::Container tests, YAMLConfiguration now works and tested
 
cin 
parents: 
421 
diff
changeset
 | 
51 $this->services->tag($this); | 
| 420 | 52 } | 
| 53 | |
| 54 sub Dispose { | |
| 55 my ($this) = @_; | |
| 56 | |
| 57 my $d; | |
| 58 foreach my $v ( values %{ $this->instances } ) { | |
| 59 if ( $d = blessed($v) && $v->can('Dispose') ) { | |
| 60 &$d($v); | |
| 61 } | |
| 62 } | |
| 
422
 
b0481c071bea
IMPL::Config::Container tests, YAMLConfiguration now works and tested
 
cin 
parents: 
421 
diff
changeset
 | 
63 | 
| 
 
b0481c071bea
IMPL::Config::Container tests, YAMLConfiguration now works and tested
 
cin 
parents: 
421 
diff
changeset
 | 
64 $this->next::method(); | 
| 413 | 65 } | 
| 412 | 66 | 
| 417 | 67 sub Require { | 
| 420 | 68 my ( $this, $class ) = @_; | 
| 69 | |
| 70 return $this->loader->Require($class); | |
| 417 | 71 } | 
| 72 | |
| 412 | 73 sub Register { | 
| 420 | 74 my ( $this, $role, $service ) = @_; | 
| 413 | 75 | 
| 420 | 76 die IMPL::InvalidArgumentException->new('service') | 
| 77 unless is( $service, Descriptor ); | |
| 78 $this->services->Register( $this->GetLinearRoleHash($role), $service ); | |
| 415 | 79 } | 
| 80 | |
| 81 sub GetLinearRoleHash { | |
| 420 | 82 my ( $this, $role ) = @_; | 
| 415 | 83 | 
| 420 | 84 die IMPL::InvalidArgumentException->new( | 
| 85 role => 'The argument is required' ) | |
| 86 unless $role; | |
| 413 | 87 | 
| 420 | 88 if ( isarray($role) ) { | 
| 89 my $tempRole = "unnamed-" . $nextRoleId++; | |
| 90 $this->roles->AddRole( $tempRole, $role ); | |
| 91 $role = $tempRole; | |
| 92 } | |
| 413 | 93 | 
| 420 | 94 $this->roles->GetLinearRoleHash($role); | 
| 413 | 95 } | 
| 96 | |
| 97 sub Resolve { | |
| 
422
 
b0481c071bea
IMPL::Config::Container tests, YAMLConfiguration now works and tested
 
cin 
parents: 
421 
diff
changeset
 | 
98 my ( $this, $role ) = @_; | 
| 413 | 99 | 
| 420 | 100 my $descriptor = $this->services->Resolve($role); | 
| 413 | 101 | 
| 
422
 
b0481c071bea
IMPL::Config::Container tests, YAMLConfiguration now works and tested
 
cin 
parents: 
421 
diff
changeset
 | 
102 return ActivationContext->new($this)->Activate($descriptor) | 
| 420 | 103 if $descriptor; | 
| 413 | 104 } | 
| 105 | |
| 106 sub ResolveAll { | |
| 420 | 107 my ( $this, $role, %opts ) = @_; | 
| 413 | 108 | 
| 420 | 109 my $all = $this->services->ResolveAll($role); | 
| 413 | 110 | 
| 420 | 111 my $context; | 
| 413 | 112 | 
| 420 | 113 my @result; | 
| 413 | 114 | 
| 420 | 115 foreach my $service (@$all) { | 
| 116 $context = ActivationContext->new($this) | |
| 421 | 117 unless $context && $opts{shared}; | 
| 413 | 118 | 
| 
422
 
b0481c071bea
IMPL::Config::Container tests, YAMLConfiguration now works and tested
 
cin 
parents: 
421 
diff
changeset
 | 
119 push @result, $context->Activate($service); | 
| 420 | 120 } | 
| 413 | 121 | 
| 420 | 122 return \@result; | 
| 412 | 123 } | 
| 407 | 124 | 
| 125 1; | |
| 126 | |
| 127 __END__ | |
| 128 | |
| 129 =pod | |
| 130 | |
| 131 =head1 NAME | |
| 132 | |
| 133 C<IMPL::Config::Container> - dependency injection container | |
| 134 | |
| 135 =head1 SYNOPSIS | |
| 136 | |
| 137 =head2 METHODS | |
| 138 | |
| 415 | 139 =head3 Resolve($role) | 
| 407 | 140 | 
| 415 | 141 =head3 ResolveAll($role, shared => $useSharedContext) | 
| 407 | 142 | 
| 415 | 143 =head3 Register($role, $service) | 
| 407 | 144 | 
| 412 | 145 =cut | 
