my $component_service_name = "${type}_${name}";
- $self->get_sub_container('component')->add_service(
+ # The 'component' sub-container will create the object, and store it's
+ # instance, which, by default, will live throughout the application.
+ # The model/view/controller sub-containers only reference the instance
+ # held in the aforementioned sub-container, and execute the ACCEPT_CONTEXT
+ # sub every time they are called, when it exists.
+ my $instance_container = $self->get_sub_container('component');
+ my $accept_context_container = $self->get_sub_container($type);
+
+ $instance_container->add_service(
Catalyst::IOC::ConstructorInjection->new(
name => $component_service_name,
class => $component,
depends_on( '/application_name' ),
depends_on( '/config' ),
],
- parameters => {
- suffix => {
- isa => 'Str',
- default => Catalyst::Utils::class2classsuffix( $component ),
- },
- },
)
- );
+ ) unless $instance_container->has_service( $component_service_name );
+ # ^ custom containers might have added the service already.
+ # we don't want to override that.
- $self->get_sub_container($type)->add_service(
+ $accept_context_container->add_service(
Catalyst::IOC::BlockInjection->new(
name => $name,
dependencies => [
depends_on( "/component/$component_service_name" ),
],
- parameters => {
- accept_context_args => {
- isa => 'ArrayRef|Undef',
- required => 0,
- default => undef,
- },
- },
- block => sub { return shift->param($component_service_name) },
+ block => sub { shift->param($component_service_name) },
)
- );
+ ) unless $accept_context_container->has_service( $name );
+ # ^ same as above
}
# FIXME: should this sub exist?
=head1 Building Containers
+=head2 build_component_subcontainer
+
+Container that stores all components, i.e. all models, views and controllers
+together. Each service is an instance of the actual component, and by default
+it lives while the application is running. Retrieving components from this
+subcontainer will instantiate the component, if it hasn't been instantiated
+already, but will not execute ACCEPT_CONTEXT.
+
=head2 build_model_subcontainer
-Container that stores all models.
+Container that stores references for all models that are inside the components
+subcontainer. Retrieving a model triggers ACCEPT_CONTEXT, if it exists.
=head2 build_view_subcontainer
-Container that stores all views.
+Same as L<build_model_subcontainer>, but for views.
=head2 build_controller_subcontainer
-Container that stores all controllers.
+Same as L<build_model_subcontainer>, but for controllers. The difference is
+that there is no ACCEPT_CONTEXT for controllers.
=head1 Building Services
The parameter list is split on comma (C<,>). You can override this method to
do your own string munging, or you can define your own macros in
-C<MyApp-E<gt>config-E<gt>{ 'Plugin::ConfigLoader' }-E<gt>{ substitutions }>.
+C<< <MyApp->config( 'Plugin::ConfigLoader' => { substitutions => { ... } } ) >>.
Example:
- MyApp->config->{ 'Plugin::ConfigLoader' }->{ substitutions } = {
- baz => sub { my $c = shift; qux( @_ ); }
- }
+ MyApp->config( 'Plugin::ConfigLoader' => {
+ substitutions => {
+ baz => sub { my $c = shift; qux( @_ ); },
+ },
+ });
The above will respond to C<__baz(x,y)__> in config strings.