## GSOC
-### Next large steps:
-
- - Moving setup_components etc into the container
-
- - Move setup_components down into the container (setup_components becomes a one or two line method in Catalyst.pm)
-
- - refactor / cleanup setup_component
-
- - Move locate_components
-
- - Move contents of setup_components
-
- - Finished documentation for ::IOC parts.
+### Next large steps, planned:
+
+For all components that have been discovered, in whatever way, we create a service:
+ - that's a catalyst component service
+ - which is basically just a constructor injection
+ - except the constructor name is COMPONENT
+ - and we're "implicitly" passing along some constructor args
+ - Lifecycle => Singleton
+
+ - Fix B::B so that Service::WithParametrs' parameters attribute has a builder
+ - Fix ConstructorInjection so that default parameters are supplied (for accept_context_args)
+ - Fix ConstructorInjection's 'suffix' - should be called 'config_key' or something, and
+ should be an attribute on the service (as it never changes), rather than a parameter
+ to the service
+
+ - We make a 'components' sub container in the main container.
+ - This gets the ConstructorInjection COMPONENT services, as model_Foo.
+ - Lifecycle of these services is Singleton
+ - This simplifies the code for MyApp->components, as it need only list one sub-container
+
+ - We create a second service (depending on the first one) for ACCEPT_CONTEXT
+ - This has a custom service which calls ACCEPT_CONTEXT when the instance is fetched
+ - Not Singleton lifecycle
+
+ Note - ACCEPT_CONTEXT can be called on app values - if you have a Model::Foo, with an ACCEPT_CONTEXT
+ and you call MyApp->model('Foo') then ACCEPT_CONTEXT gets invoked with a $c of 'MyApp' (this is not\
+ the normal case, but we need to preserve for compat)
+
+### Next steps - less planned:
- Creating service()-like sugar for component
- Using the sugar added in the previous item
- Test when Model::Foo depends_on Model::Bar
- - Allowing people to change component lifecycles
-
- role Service::WithAcceptContext {}
- role Service::WithCOMPONENT {}
- class Service::CatalystComponent extends Service with (WithAcceptContext, WithCOMPONENT) {}
-
- a) configure additional services in that container
- - super simple container $default_container => as { more services };
- class MyApp::Container extends Catalyst::Container {
- use Bread::Board; # Or our own sugar?
- method BUILD { container $self => as {
- service model => ...; # some constructor injection to MyApp::Model or something
- container Model => as {
- component Foo => (dependencies => ['/model']); # As per default!
- component Bar => (dependencies => ['/model/Foo']); # Magic!
- };
- # Note - implementation of BB may need to be changed to support making sure existing
- # services actually get overridden. not sure how the default container behaves when doing that
- # above code would build the constructor injection as it currently does,
- # defaulting to the class name in the right namespace as declared by the surrounding container
- # as well as adding using the catalyst-specific service class
- } }
- };
- b) make component services depend on that, and
-
-
- c) ask for those
- services declared in a) outside of a web context
- simple as well. $customised_container->fetch('service')->get # or whatever the api was
-
-19:23 < andrewalker> edenc, when explaining to me how it should be, drafted this: https://gist.github.com/1098186
-19:26 < edenc> I like the possibility of being able to provide a backwards-compatible structure which we can muck around with by configuring B::B
-19:26 <@rafl> so, the request context clearly isn't a service
-19:27 <@rafl> but that's ok. there's parametrised services
-19:27 < edenc> yeah, that was a draft
-19:27 <@rafl> the outer Foo service is pretty much what i'd expect Service::WithAcceptContext to do, except with a dependency on a context instead of a service parameter
-19:32 <@rafl> actually having services for the pre-ACCEPT_CONTEXT bits is what i want to think about
-
-### To polish off
-
- - Document current methods
- - + $class->container->get_sub_container('model')->make_single_default;
-+ $class->container->get_sub_container('view')->make_single_default;
+ - Tests for using the container outside of Catalyst
+ - Custom container which adds some (very simple) services which are initialized from
+ the application config file (note plain services, not components)
+ - Depend on (and test) these inside Catalyst
+ - Test loading container outside Catalyst, and these services working
+ - Test Catalyst / MyApp is not loaded
+
+#### Extending my app, notes
+
+Basically try to implement something like this (starting out without the sugar!), and see how it breaks
+and what needs to be done to fix it!
+
+##### Eventual syntax
+
+package MyApp::Container;
+use Catalyst::IOC;
+
+ container $self, as {
+ container model => as {
+ component Foo => (); # As per default!
+ component Bar => (dependencies => ['/model/Foo']); # Magic!
+ component Baz => ( lifecycle => 'InstancePerContext );
+ component Quux => ( lifecycle => 'Singleton' ); # ACCEPT_CONTEXT not called
+ };
+ # Note - implementation of BB may need to be changed to support making sure existing
+ # services actually get overridden. not sure how the default container behaves when doing that
+ # above code would build the constructor injection as it currently does,
+ # defaulting to the class name in the right namespace as declared by the surrounding container
+ # as well as adding using the catalyst-specific service class
+ };
+
+1;
+
+##### To start with
+
+package MyApp::Container;
+use Moose;
+
+extends 'Catalyst::Container;
+
+after BUILD => sub {
+ my $self = shift;
+ my $model_container = $self->get_sub_container('model');
+ my $service = Catalyst::IOC::ConstructorInjection->new(
+ name => 'Baz',
+ class => 'MyApp::Model::Baz',
+ dependencies => [
+ depends_on( '/application_name' ),
+ depends_on( '/config' ),
+ depends_on( '/model/Foo' ),
+ ],
+ lifecycle => 'InstancePerContext',
+ );
+ $model_container->add_service( 'Foo', $service );
+};
+
+### To polish off / t0m review
+
+ +Same as L<build_model_subcontainer>, but for controllers. The difference is
+ +that there is no ACCEPT_CONTEXT for controllers.
+ ^^ This is wrong!!
+
+ - my $accept_context_args = $self->param('accept_context_args');
+ + my $accept_context_args = $params{accept_context_args};
+ ^^ This (may be) wrong! I am thinking the service should be allowed to mangle the
+ accept_context args, no?
+ Without this change, the user could make a custom service which mangled the param, and use
+ Catalyst/IOC/Service/WithAcceptContext.pm, with this change, that module will always see the
+ un-mangled version?? However, without this change, shit doesn't work...
### Known issues
- expand_component_module
+ - People wrapping locate_components in Catalyst.pm