Mercurial > pub > Impl
annotate lib/IMPL/Config/Container.pm @ 422:b0481c071bea ref20150831
IMPL::Config::Container tests, YAMLConfiguration now works and tested
author | cin |
---|---|
date | Sun, 20 Aug 2017 00:20:41 +0300 |
parents | 7798345304bc |
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 |