dbb01849a5741a7cd62388ce145347341aad2c61
[catagits/Catalyst-Runtime.git] / lib / Catalyst / IOC.pm
1 package Catalyst::IOC;
2 use strict;
3 use warnings;
4 use Bread::Board qw/depends_on/;
5 use Catalyst::IOC::ConstructorInjection;
6
7 # FIXME - All of these imports need to get the importing package
8 #         as the customise_container and current_container variables
9 #         NEED to be in the containers package so there can be multiple
10 #         containers..
11 use Sub::Exporter -setup => {
12     exports => [qw/
13         depends_on
14         component
15         model
16         container
17     /],
18     groups  => { default => [qw/
19         depends_on
20         component
21         model
22         container
23     /]},
24 };
25 #use Sub::Exporter -setup => [
26 #    qw(
27 #        Bread::Board::as
28 #        Bread::Board::container
29 #        Bread::Board::depends_on
30 #        Bread::Board::service
31 #        Bread::Board::alias
32 #        Bread::Board::wire_names
33 #        Bread::Board::include
34 #        Bread::Board::typemap
35 #        Bread::Board::infer
36 #    )
37 #];
38 # I'm probably doing it wrong.
39 # Anyway, I'll just use Moose::Exporter. Do I really have to use Sub::Exporter?
40 #use Moose::Exporter;
41 #Moose::Exporter->setup_import_methods(
42 #    also => ['Bread::Board'],
43 #);
44 our $customise_container;
45 our $current_container;
46
47 sub container (&) {
48     my $code = shift;
49     $customise_container = sub {
50         warn("In customise container");
51         local $current_container = shift();
52         $code->();
53     };
54 }
55
56 sub model (&) {
57     my $code = shift;
58     local $current_container = $current_container->get_sub_container('model');
59     $code->();
60 }
61
62 sub component {
63     my ($name, %args) = @_;
64     $args{dependencies} ||= {};
65     $args{dependencies}{application_name} = depends_on( '/application_name' );
66
67     # FIXME - check $args{type} here!
68
69     my $component_name = join '::', (
70         $current_container->resolve(service => '/application_name'),
71         ucfirst($current_container->name),
72         $name
73     );
74
75     my $service = Catalyst::IOC::ConstructorInjection->new(
76         %args,
77         name             => $name,
78         lifecycle        => 'Singleton',
79         # XX FIXME - needs to become possible to intuit catalyst_component_name
80         #            from dependencies (like config)
81         catalyst_component_name => $component_name,
82     );
83     $current_container->add_service($service);
84 }
85
86 1;
87
88 # FIXME - should the code example below be on this file or Catalyst::IOC::Container?
89
90 __END__
91
92 =pod
93
94 =head1 NAME
95
96 Catalyst::IOC - IOC for Catalyst, based on Bread::Board
97
98 =head1 SYNOPSIS
99
100     package MyApp::Container;
101     use Catalyst::IOC;
102
103     sub BUILD {
104         my $self = shift;
105
106         container $self => as {
107             container model => as {
108
109                 # default component
110                 component Foo => ();
111
112                 # model Bar needs model Foo to be built before
113                 # and Bar's constructor gets Foo as a parameter
114                 component Bar => ( dependencies => [
115                     depends_on('/model/Foo'),
116                 ]);
117
118                 # Baz is rebuilt once per HTTP request
119                 component Baz => ( lifecycle => 'Request' );
120
121                 # built only once per application life time
122                 component Quux => ( lifecycle => 'Singleton' );
123
124                 # built once per app life time and uses an external model,
125                 # outside the default directory
126                 # no need for wrappers or Catalyst::Model::Adaptor
127                 component Fnar => (
128                     lifecycle => 'Singleton',
129                     class => 'My::External::Class',
130                 );
131             };
132         }
133     }
134
135 =head1 DESCRIPTION
136
137 =head1 METHODS
138
139 =head1 AUTHORS
140
141 Catalyst Contributors, see Catalyst.pm
142
143 =head1 SEE ALSO
144
145 L<Bread::Board>
146
147 =head1 COPYRIGHT
148
149 This library is free software. You can redistribute it and/or modify it under
150 the same terms as Perl itself.
151
152 =cut