Mercurial > pub > Impl
annotate lib/IMPL/Config/Container.pm @ 427:09e0086a82a7 ref20150831 tip
Merge
| author | cin |
|---|---|
| date | Tue, 15 May 2018 00:51:33 +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 |
