407
|
1 package IMPL::Config::ActivationContext;
|
|
2
|
416
|
3 use IMPL::lang qw(:base);
|
407
|
4 use IMPL::Const qw(:prop);
|
|
5 use IMPL::Exception();
|
|
6 use IMPL::declare {
|
|
7 require => {
|
416
|
8 Bag => 'IMPL::Config::ServicesBag',
|
|
9 ServiceNotFoundException => 'IMPL::Config::ServiceNotFoundException',
|
407
|
10 },
|
|
11 base => {
|
|
12 'IMPL::Object' => '@_'
|
|
13 },
|
|
14 props => {
|
415
|
15 container => PROP_RW,
|
407
|
16 _services => PROP_RW,
|
415
|
17 _cache => PROP_RW,
|
|
18 _stack => PROP_RW
|
407
|
19 }
|
|
20 };
|
|
21
|
415
|
22 sub CTOR {
|
|
23 my ( $this, $container ) = @_;
|
|
24
|
|
25 $this->container($container)
|
416
|
26 or die IMPL::InvalidArgumentException->new('container');
|
|
27 $this->_cache({});
|
|
28 $this->_stack([]);
|
407
|
29 }
|
|
30
|
|
31 sub EnterScope {
|
415
|
32 my ( $this, $name, $services ) = @_;
|
|
33
|
407
|
34 my $info = { name => $name };
|
415
|
35
|
|
36 if ($services) {
|
416
|
37 die IMPL::InvalidArgumentException->new(
|
|
38 services => 'An array is required' )
|
|
39 unless isarray($services);
|
|
40
|
|
41 my $bag = $this->container->serviceCache->{ ref($services) };
|
|
42
|
|
43 unless ($bag) {
|
|
44 my $container = $this->container;
|
|
45 $bag = Bag->new( $this->_services );
|
415
|
46
|
416
|
47 $bag->Register(
|
|
48 $container->GetLinearRoleHash( $_->{role}, $_->{descriptor} ) )
|
|
49 foreach @$services;
|
|
50
|
|
51 $container->serviceCache->{ ref($services) } = $bag;
|
|
52 }
|
|
53
|
|
54 $info->{services} = $this->_services;
|
|
55 $this->_services($bag);
|
407
|
56 }
|
415
|
57
|
416
|
58 push @{$this->_stack}, $info;
|
407
|
59 }
|
|
60
|
|
61 sub LeaveScope {
|
|
62 my ($this) = @_;
|
415
|
63
|
416
|
64 my $info = pop @{$this->_stack}
|
|
65 or die IMPL::InvalidOperationException->new();
|
|
66
|
|
67 $this->_services( $info->{services} ) if $info->{services};
|
|
68 }
|
415
|
69
|
416
|
70 sub GuardScope {
|
|
71 my ( $this, $name, $services, $action ) = @_;
|
|
72
|
|
73 $this->EnterScope( $name, $service );
|
|
74 eval { $action ($this) if $action; } my $err = $@;
|
|
75 $this->LeaveScope();
|
|
76 die $err if $err;
|
415
|
77 }
|
|
78
|
|
79 sub Resolve {
|
416
|
80 my ( $this, $role, %opts ) = @_;
|
|
81
|
|
82 my $d = $this->_services->Reolve($role);
|
|
83
|
|
84 unless($d) {
|
|
85 die ServiceNotFoundException->new($role) unless $opts{optional};
|
|
86 return $opts{default};
|
|
87 } else {
|
|
88 return $d->Activate($this);
|
|
89 }
|
415
|
90 }
|
|
91
|
|
92 sub Clone {
|
|
93 my ($this) = @_;
|
416
|
94
|
|
95 my $clone = SELF->new($this->container);
|
|
96
|
|
97 $clone->_
|
407
|
98 }
|
|
99
|
|
100 1;
|
|
101 __END__
|
|
102
|
|
103 =pod
|
|
104
|
|
105 =head1 NAME
|
|
106
|
|
107 C<IMPL::Config::ActivationContext> - an activation context for the service
|
|
108
|
|
109 =head1 SYNOPSIS
|
|
110
|
|
111 For the internal use only
|
|
112
|
|
113 =head1 MEMBERS
|
|
114
|
|
115 =head2 METHODS
|
|
116
|
416
|
117 =head3 Resolve($serviceId)
|
407
|
118
|
415
|
119 =cut
|