Mercurial > pub > Impl
comparison lib/IMPL/Config/ActivationContext.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 |
comparison
equal
deleted
inserted
replaced
421:7798345304bc | 422:b0481c071bea |
---|---|
1 package IMPL::Config::ActivationContext; | 1 package IMPL::Config::ActivationContext; |
2 | 2 |
3 use IMPL::lang qw(:base); | 3 use IMPL::lang qw(:base); |
4 use IMPL::Const qw(:prop); | |
5 use IMPL::Exception(); | 4 use IMPL::Exception(); |
6 use IMPL::declare { | 5 use IMPL::declare { |
7 require => { | 6 require => { |
8 Bag => 'IMPL::Config::ServicesBag', | 7 Bag => 'IMPL::Config::Bag', |
9 ServiceNotFoundException => 'IMPL::Config::ServiceNotFoundException', | 8 ServiceNotFoundException => 'IMPL::Config::ServiceNotFoundException', |
9 Descriptor => '-IMPL::Config::Descriptor' | |
10 }, | 10 }, |
11 base => { | 11 base => { |
12 'IMPL::Object' => '@_' | 12 'IMPL::Object' => '@_' |
13 }, | 13 }, |
14 props => [ | 14 props => [ |
15 container => PROP_RW, | 15 container => 'rw', |
16 instances => PROP_RW, | 16 owner => 'rw', |
17 _services => PROP_RW, | 17 instances => 'rw', |
18 _stack => PROP_RW | 18 name => 'rw', |
19 _services => 'rw', | |
20 _stack => 'rw' | |
19 ] | 21 ] |
20 }; | 22 }; |
21 | 23 |
22 sub CTOR { | 24 sub CTOR { |
23 my ( $this, $container ) = @_; | 25 my ( $this, $container ) = @_; |
24 | 26 |
25 $this->container($container) | 27 $this->container($container) |
26 or die IMPL::InvalidArgumentException->new('container'); | 28 or die IMPL::InvalidArgumentException->new('container'); |
29 $this->owner($container); | |
27 $this->_services( $container->services ); | 30 $this->_services( $container->services ); |
28 $this->instances( {} ); | 31 $this->instances( {} ); |
29 $this->_stack( [] ); | 32 $this->_stack( [] ); |
30 } | 33 } |
31 | 34 |
32 sub EnterScope { | 35 sub EnterScope { |
33 my ( $this, $name, $services ) = @_; | 36 my ( $this, $name, $services, $container ) = @_; |
34 | 37 |
35 my $info = { name => $name }; | 38 my $info = { name => $this->name }; |
39 | |
40 $this->name($name); | |
41 | |
42 if ( $container && $this->container != $container ) { | |
43 $info->{container} = $this->container; | |
44 $this->container($container); | |
45 } | |
36 | 46 |
37 if ($services) { | 47 if ($services) { |
38 die IMPL::InvalidArgumentException->new( | 48 die IMPL::InvalidArgumentException->new( |
39 services => 'An array is required' ) | 49 services => 'An array is required' ) |
40 unless isarray($services); | 50 unless isarray($services); |
41 | 51 |
42 my $bag = $this->container->serviceCache->{ ref($services) }; | 52 my $bag = $this->container->serviceCache->{ ref($services) }; |
43 | 53 |
44 unless ($bag) { | 54 unless ($bag) { |
45 my $container = $this->container; | |
46 $bag = Bag->new( $this->_services ); | 55 $bag = Bag->new( $this->_services ); |
56 $bag->tag( $container || $this->container ); | |
47 | 57 |
48 # | 58 $bag->Register( $container->GetLinearRoleHash( $_->{role} ), |
49 $bag->Register( | 59 $_->{descriptor} ) |
50 $container->GetLinearRoleHash( $_->{role}, $_->{descriptor} ) ) | |
51 foreach @$services; | 60 foreach @$services; |
52 | 61 |
53 $container->serviceCache->{ ref($services) } = $bag; | 62 $container->serviceCache->{ ref($services) } = $bag; |
54 } | 63 } |
55 | 64 |
64 my ($this) = @_; | 73 my ($this) = @_; |
65 | 74 |
66 my $info = pop @{ $this->_stack } | 75 my $info = pop @{ $this->_stack } |
67 or die IMPL::InvalidOperationException->new(); | 76 or die IMPL::InvalidOperationException->new(); |
68 | 77 |
69 $this->_services( $info->{services} ) if $info->{services}; | 78 $this->name( $info->{name} ); |
79 $this->_services( $info->{services} ) if $info->{services}; | |
80 $this->conatiner( $info->{container} ) if $info->{container}; | |
70 } | 81 } |
71 | 82 |
72 sub Resolve { | 83 sub Resolve { |
73 my ( $this, $role, %opts ) = @_; | 84 my ( $this, $role, %opts ) = @_; |
74 | 85 |
75 my $d = $this->_services->Resolve($role); | 86 #change of the container may occur only due resolution of the dependency |
87 my ( $d, $bag ) = $this->_services->Resolve($role); | |
76 | 88 |
77 unless ($d) { | 89 unless ($d) { |
78 die ServiceNotFoundException->new($role) unless $opts{optional}; | 90 die ServiceNotFoundException->new(serviceName => $role) unless $opts{optional}; |
79 return $opts{default}; | 91 return $opts{default}; |
80 } | 92 } |
81 else { | 93 else { |
82 return $d->Activate($this); | 94 $this->EnterScope( $d->GetName(), $d->services(), $bag->tag() ); |
95 my $instance = $d->Activate($this); | |
96 $this->LeaveScope(); | |
97 return $instance; | |
83 } | 98 } |
99 } | |
100 | |
101 sub Activate { | |
102 my ( $this, $d ) = @_; | |
103 $this->EnterScope( $d->GetName(), $d->services() ); | |
104 my $instance = $d->Activate($this); | |
105 $this->LeaveScope(); | |
106 return $instance; | |
84 } | 107 } |
85 | 108 |
86 sub Clone { | 109 sub Clone { |
87 my ($this) = @_; | 110 my ($this) = @_; |
88 | 111 |
89 my $clone = SELF->new( $this->container ); | 112 my $clone = SELF->new( $this->owner ); |
90 | 113 $clone->name($this->name); |
114 $clone->container( $this->container ); | |
91 $clone->_services( $this->_services ); | 115 $clone->_services( $this->_services ); |
92 $clone->instances( { %{ $this->instances } } ); | 116 $clone->instances( $this->instances ); |
93 $clone->_stack( [ @{ $this->_stack } ] ); | 117 $clone->_stack( [ @{ $this->_stack } ] ); |
94 | 118 |
95 return $clone; | 119 return $clone; |
96 } | 120 } |
97 | 121 |
108 | 132 |
109 For the internal use only | 133 For the internal use only |
110 | 134 |
111 =head1 MEMBERS | 135 =head1 MEMBERS |
112 | 136 |
137 =head2 PROPERTIES | |
138 | |
139 =head3 [get] container | |
140 | |
141 Current container for the activation context, this container changes | |
142 during resolution process to match the one in which the resulting | |
143 descriptor were defined. Descriptors can use this property to | |
144 access the cache of theirs container. | |
145 | |
146 =head3 [get] owner | |
147 | |
148 The container which created this context. Descriptors can use this | |
149 property during theirs activation. | |
150 | |
151 =head3 [get] instances | |
152 | |
153 The activation cache which can be used to store instances during | |
154 single resolution process. | |
155 | |
113 =head2 METHODS | 156 =head2 METHODS |
114 | 157 |
115 =head3 Resolve($serviceId) | 158 =head3 Resolve($serviceId): $instance |
159 | |
160 Activates and returns an instance specified by C<$serviceId> | |
161 | |
162 =head3 Activate($descriptor): $instance | |
163 | |
164 Activates and returns an instance of the services for the specified descriptor/ | |
116 | 165 |
117 =cut | 166 =cut |