407
|
1 package IMPL::Config::Container;
|
412
|
2 use strict;
|
|
3
|
413
|
4 use IMPL::Exception();
|
412
|
5 use IMPL::lang qw(:base);
|
|
6 use IMPL::declare {
|
|
7 require => {
|
413
|
8 Descriptor => 'IMPL::Config::Descriptor',
|
|
9 ValueDescriptor => 'IMPL::Config::ValueDescriptor',
|
|
10 ActivationContext => 'IMPL::Config::ActivationContext',
|
|
11 Hierarchy => 'IMPL::Config::Hierarchy',
|
415
|
12 Bag => 'IMPL::Config::Bag',
|
|
13 Loader => 'IMPL::Code::Loader'
|
412
|
14 },
|
|
15 base => [
|
|
16 'IMPL::Object' => undef
|
|
17 ],
|
|
18 props => [
|
413
|
19 roles => 'r',
|
|
20 services => 'r',
|
|
21 instances => 'r',
|
415
|
22 parent => 'r',
|
|
23 root => 'r',
|
|
24 loader => 'r'
|
412
|
25 ]
|
|
26 };
|
|
27
|
|
28 my $nextRoleId = 1;
|
|
29
|
413
|
30 sub CTOR {
|
415
|
31 my ( $this, $parent, %opts ) = @_;
|
413
|
32
|
|
33 $this->instances( {} );
|
|
34
|
415
|
35 $this->loader( $opts{loader} || Loader->safe );
|
|
36
|
413
|
37 if ($parent) {
|
|
38 $this->roles( Hierarchy->new( $parent->roles ) );
|
|
39 $this->services( Bag->new( $parent->services ) );
|
|
40 $this->parent($parent);
|
415
|
41 $this->root( $parent->root );
|
413
|
42 }
|
|
43 else {
|
|
44 $this->roles( Hierarchy->new() );
|
|
45 $this->services( Bag->new() );
|
415
|
46 $this->root($this);
|
413
|
47 }
|
|
48 }
|
412
|
49
|
417
|
50 sub Require {
|
|
51 my ($this, $class) = @_;
|
|
52
|
|
53 return $this->loader->Require($class);
|
|
54 }
|
|
55
|
412
|
56 sub Register {
|
413
|
57 my ( $this, $role, $service ) = @_;
|
|
58
|
415
|
59 die IMPL::InvalidArgumentException->new('service')
|
|
60 unless is( $service, Descriptor );
|
|
61 $this->services->Register( $this->GetLinearRoleHash($role), $service );
|
|
62 }
|
|
63
|
|
64 sub GetLinearRoleHash {
|
|
65 my ( $this, $role ) = @_;
|
|
66
|
413
|
67 die IMPL::InvalidArgumentException->new(
|
|
68 role => 'The argument is required' )
|
|
69 unless $role;
|
|
70
|
|
71 if ( isarray($role) ) {
|
|
72 my $tempRole = "unnamed-" . $nextRoleId++;
|
417
|
73 $this->roles->AddRole( $tempRole, $role );
|
413
|
74 $role = $tempRole;
|
412
|
75 }
|
413
|
76
|
415
|
77 $this->roles->GetLinearRoleHash($role);
|
413
|
78 }
|
|
79
|
|
80 sub Resolve {
|
|
81 my ( $this, $role, %opts ) = @_;
|
|
82
|
|
83 my $descriptor = $this->services->Resolve($role);
|
|
84
|
|
85 return $descriptor->Activate( ActivationContext->new($this) )
|
417
|
86 if $descriptor;
|
413
|
87
|
|
88 return $opts{default} if exists $opts{default};
|
|
89 }
|
|
90
|
|
91 sub ResolveAll {
|
|
92 my ( $this, $role, %opts ) = @_;
|
|
93
|
|
94 my $all = $this->services->ResolveAll($role);
|
|
95
|
|
96 my $context;
|
|
97
|
|
98 my @result;
|
|
99
|
|
100 foreach my $service (@$all) {
|
|
101 $context = ActivationContext->new($this)
|
|
102 unless $context || $opts{shared};
|
|
103
|
|
104 push @result, $service->Activate($context);
|
|
105 }
|
|
106
|
|
107 return \@result;
|
412
|
108 }
|
407
|
109
|
|
110 1;
|
|
111
|
|
112 __END__
|
|
113
|
|
114 =pod
|
|
115
|
|
116 =head1 NAME
|
|
117
|
|
118 C<IMPL::Config::Container> - dependency injection container
|
|
119
|
|
120 =head1 SYNOPSIS
|
|
121
|
|
122 =head2 METHODS
|
|
123
|
415
|
124 =head3 Resolve($role)
|
407
|
125
|
415
|
126 =head3 ResolveAll($role, shared => $useSharedContext)
|
407
|
127
|
415
|
128 =head3 Register($role, $service)
|
407
|
129
|
412
|
130 =cut
|