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
|
|
50 sub Register {
|
413
|
51 my ( $this, $role, $service ) = @_;
|
|
52
|
415
|
53 die IMPL::InvalidArgumentException->new('service')
|
|
54 unless is( $service, Descriptor );
|
|
55 $this->services->Register( $this->GetLinearRoleHash($role), $service );
|
|
56 }
|
|
57
|
|
58 sub GetLinearRoleHash {
|
|
59 my ( $this, $role ) = @_;
|
|
60
|
413
|
61 die IMPL::InvalidArgumentException->new(
|
|
62 role => 'The argument is required' )
|
|
63 unless $role;
|
|
64
|
|
65 if ( isarray($role) ) {
|
|
66 my $tempRole = "unnamed-" . $nextRoleId++;
|
|
67 $this->role->AddRole( $tempRole, $role );
|
|
68 $role = $tempRole;
|
412
|
69 }
|
413
|
70
|
415
|
71 $this->roles->GetLinearRoleHash($role);
|
413
|
72 }
|
|
73
|
|
74 sub Resolve {
|
|
75 my ( $this, $role, %opts ) = @_;
|
|
76
|
|
77 my $descriptor = $this->services->Resolve($role);
|
|
78
|
|
79 return $descriptor->Activate( ActivationContext->new($this) )
|
|
80 if $descirptor;
|
|
81
|
|
82 return $opts{default} if exists $opts{default};
|
|
83 }
|
|
84
|
|
85 sub ResolveAll {
|
|
86 my ( $this, $role, %opts ) = @_;
|
|
87
|
|
88 my $all = $this->services->ResolveAll($role);
|
|
89
|
|
90 my $context;
|
|
91
|
|
92 my @result;
|
|
93
|
|
94 foreach my $service (@$all) {
|
|
95 $context = ActivationContext->new($this)
|
|
96 unless $context || $opts{shared};
|
|
97
|
|
98 push @result, $service->Activate($context);
|
|
99 }
|
|
100
|
|
101 return \@result;
|
412
|
102 }
|
407
|
103
|
|
104 1;
|
|
105
|
|
106 __END__
|
|
107
|
|
108 =pod
|
|
109
|
|
110 =head1 NAME
|
|
111
|
|
112 C<IMPL::Config::Container> - dependency injection container
|
|
113
|
|
114 =head1 SYNOPSIS
|
|
115
|
|
116 =head2 METHODS
|
|
117
|
415
|
118 =head3 Resolve($role)
|
407
|
119
|
415
|
120 =head3 ResolveAll($role, shared => $useSharedContext)
|
407
|
121
|
415
|
122 =head3 Register($role, $service)
|
407
|
123
|
412
|
124 =cut
|