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