X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FIOC.pm;h=19e2c47df89da117dbe18915e73bbe352c8658eb;hb=96c9f5d4c9cebf815970a5ea94b90ad693ebaa93;hp=7072aef610c909b261d47cda54f42aa92a0c3322;hpb=4bb290531214f4f283a7e1ac58d0911d882c3d23;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst/IOC.pm b/lib/Catalyst/IOC.pm index 7072aef..19e2c47 100644 --- a/lib/Catalyst/IOC.pm +++ b/lib/Catalyst/IOC.pm @@ -3,19 +3,22 @@ use strict; use warnings; use Bread::Board qw/depends_on/; use Catalyst::IOC::ConstructorInjection; -no strict 'refs'; use Sub::Exporter -setup => { exports => [qw/ depends_on component model + view + controller container /], groups => { default => [qw/ depends_on component model + view + controller container /]}, }; @@ -23,18 +26,25 @@ use Sub::Exporter -setup => { sub container (&) { my $code = shift; my $caller = caller; + + no strict 'refs'; ${"${caller}::customise_container"} = sub { local ${"${caller}::current_container"} = shift; $code->(); }; } -sub model (&) { _subcontainer( shift, caller, 'model' ) } -sub view (&) { _subcontainer( shift, caller, 'view' ) } -sub controller (&) { _subcontainer( shift, caller, 'controller' ) } +sub model (&) { &_subcontainer } +sub view (&) { &_subcontainer } +sub controller (&) { &_subcontainer } + +sub _subcontainer { + my $code = shift; + + my ( $caller, $f, $l, $subcontainer ) = caller(1); + $subcontainer =~ s/^Catalyst::IOC:://; -sub _subcontainer (&$$) { - my ( $code, $caller, $subcontainer ) = @_; + no strict 'refs'; local ${"${caller}::current_container"} = ${"${caller}::current_container"}->get_sub_container($subcontainer); $code->(); @@ -42,31 +52,38 @@ sub _subcontainer (&$$) { sub component ($;%) { my ($name, %args) = @_; - my $caller = caller; + my $current_container; + + { + no strict 'refs'; + my $caller = caller; + $current_container = ${"${caller}::current_container"}; + } + $args{dependencies} ||= {}; - $args{dependencies}{application_name} = depends_on( '/application_name' ); + $args{dependencies}{catalyst_application} = depends_on( '/catalyst_application' ); - my $lifecycle = $args{lifecycle}; - my %catalyst_lifecycles = map { $_ => 1 } qw/ COMPONENTSingleton Request /; - $args{lifecycle} = $lifecycle - ? $catalyst_lifecycles{$lifecycle} ? "+Catalyst::IOC::LifeCycle::$lifecycle" : $lifecycle - : 'Singleton' + my $lifecycle = $args{lifecycle} || 'Singleton'; + $args{lifecycle} = grep( m/^$lifecycle$/, qw/COMPONENTSingleton Request/ ) + ? "+Catalyst::IOC::LifeCycle::$lifecycle" + : $lifecycle ; # FIXME - check $args{type} here! my $component_name = join '::', ( - ${"${caller}::current_container"}->resolve(service => '/application_name'), - ucfirst(${"${caller}::current_container"}->name), + $current_container->resolve(service => '/catalyst_application'), + ucfirst($current_container->name), $name ); - my $service = Catalyst::IOC::ConstructorInjection->new( - %args, - name => $name, - catalyst_component_name => $component_name, + $current_container->add_service( + Catalyst::IOC::ConstructorInjection->new( + %args, + name => $name, + catalyst_component_name => $component_name, + ) ); - ${"${caller}::current_container"}->add_service($service); } 1; @@ -82,54 +99,70 @@ Catalyst::IOC - IOC for Catalyst, based on Bread::Board =head1 SYNOPSIS package MyApp::Container; + use Moose; use Catalyst::IOC; - - sub BUILD { - my $self = shift; - - container $self => as { - container model => as { - - # default component - component Foo => (); - - # model Bar needs model Foo to be built before - # and Bar's constructor gets Foo as a parameter - component Bar => ( dependencies => [ - depends_on('/model/Foo'), - ]); - - # Baz is rebuilt once per HTTP request - component Baz => ( lifecycle => 'Request' ); - - # built only once per application life time - component Quux => ( lifecycle => 'Singleton' ); - - # built once per app life time and uses an external model, - # outside the default directory - # no need for wrappers or Catalyst::Model::Adaptor - component Fnar => ( - lifecycle => 'Singleton', - class => 'My::External::Class', - ); - }; - } + extends 'Catalyst::IOC::Container'; + + container { + model { + # default component + component Foo => (); + + # model Bar needs model Foo to be built before + # and Bar's constructor gets Foo as a parameter + component Bar => ( dependencies => [ + depends_on('/model/Foo'), + ]); + + # Baz is rebuilt once per HTTP request + component Baz => ( lifecycle => 'Request' ); + + # built only once per application life time + component Quux => ( lifecycle => 'Singleton' ); + + # built once per app life time and uses an external model, + # outside the default directory + # no need for wrappers or Catalyst::Model::Adaptor + component Fnar => ( + lifecycle => 'Singleton', + class => 'My::External::Class', + ); + }; + view { + component HTML => (); + }; + controller { + component Root => (); + }; } =head1 DESCRIPTION +Catalyst::IOC provides "sugar" methods to extend the behavior of the default +Catalyst container. + =head1 METHODS =head2 container +Sets up the root container to be customised. + =head2 model +Sets up the model container to be customised. + =head2 view +Sets up the view container to be customised. + =head2 controller +Sets up the controller container to be customised. + =head2 component +Adds a component to the sub-container. Works like L. + =head1 AUTHORS Catalyst Contributors, see Catalyst.pm