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