setting correct return value for components
[catagits/Catalyst-Runtime.git] / TODO
1 # Known Bugs:
2
3    - Bug ->go or ->visit causes actions which have Args or CaptureArgs called
4      twice when called via ->go or ->visit.
5
6      Test app: http://github.com/bobtfish/catalyst-app-bug-go_chain/tree/master
7
8 # Compatibility warnings to add:
9
10   - $self->config should warn as config should only ever be called as a
11     class method (TESTS).
12
13 # Proposed functionality / feature additions:
14
15 ## Log setup needs to be less lame
16
17 So Catalyst::Plugin::Log::* can die
18 in a fire. Having $c->log_class would be a good start. kane volunteered
19 to do some of this.
20
21 Simple example: Catalyst::Plugin::Log::Colorful should just be a
22 subclass of Catalyst::Log, no ::Plugin:: needed.
23
24 See also: Catalyst::Plugin::Log::Dispatch and
25 http://github.com/willert/catalyst-plugin-log4perl-simple/tree
26
27 ## throw away the restarter and allow using the restarters Plack provides
28
29 ## be smarter about how we use PSGI - not every response needs to be delayed
30     and streaming
31
32 #  The horrible hack for plugin setup - replacing it:
33
34  * Have a look at the Devel::REPL BEFORE_PLUGIN stuff
35    I wonder if what we need is that combined with plugins-as-roles
36
37 # App / ctx split:
38
39   NOTE - these are notes that t0m thought up after doing back compat for
40          catalyst_component_class, may be inaccurate, wrong or missing things
41          bug mst (at least) to correct before trying more than the first 2
42          steps. Please knock yourself out on the first two however :)
43
44   - Eliminate actions in MyApp from the main test suite
45   - Uncomment warning in C::C::register_action_methods, add tests it works
46     by mocking out the logging..
47   - Remove MyApp @ISA controller (ask metaclass if it has attributes, and if
48                                   so you need back compat :/)
49   - Make Catalyst::Context, move the per request stuff in there, handles from
50     main app class to delegate
51   - Make an instance of the app class which is a global variable
52   - Make new instance of the context class, not the app class per-request
53   - Remove the components as class data, move to instance data on the app
54     class (you probably have to do this for _all_ the class data, good luck!)
55   - Make it possible for users to spin up different instances of the app class
56     (with different config etc each)
57   - Profit! (Things like changing the complete app config per vhost, i.e.
58     writing a config loader / app class role which dispatches per vhost to
59     differently configured apps is piss easy)
60
61 ## GSOC
62
63 ### Final steps for GSOC
64
65 ##### Things that work:
66
67     - the default container loads all components, calls ACCEPT_CONTEXT() when appropriate, and COMPONENT() when appropriate, behaving like current Catalyst does
68
69     - its possible to create a custom container, and override the components you want. Lifecycle, class, dependencies, all overridable.
70
71     - config files are loaded without Catalyst::Plugin::ConfigLoader
72
73     - per request life cycle somewhat works
74
75     - external modules are loaded just using a custom container, much like Catalyst::Model::Adaptor
76
77 ##### Things that don't work:
78
79     - expand_component_module
80
81     - Some back compat
82         - wrappers around setup_component, setup_components in Catalyst.pm
83         - $instance->expand_modules
84         - search_extra
85         - Crazy tests for things such as:
86            sub COMPONENT {
87              ...
88              *${appclass}::Model::TopLevel::GENERATED::ACCEPT_CONTEXT = sub { ... };
89              ...
90            }
91
92 ##### Items for discussion and planning
93 # (in no particular order, just numbered to be more easily refered to)
94
95   1) per request life cycle
96
97   2) sugar syntax
98
99   3) when / when not COMPONENT should be called
100
101   4) problems when get_all_components() is called when there is no 'context' yet
102
103   5) Back compat problems:
104      - expand_component_module
105      - $instance->expand_modules
106      - search_extra
107      - what to do when a user overrides the locate_components method?
108
109   6) locate_components service vs setup_components method
110      - can we be more lazy?
111      - should setup_components be a service that things like the ->component lookup
112        can depend on?
113
114   7) $class->log->warn is being used to give warnings, but maybe there is a
115      better way to do it
116
117   8) the ConstructorInjection depends on the application_name, which probably
118      makes app/ctx split harder. We need a way to get the application instance
119      passed properly.
120
121   9) there is a call in Catalyst::Controller to catalyst_component_name class
122      accessor (which doesn't exist anymore).
123
124  10) make ACCEPT_CONTEXT and COMPONENT optional in Catalyst::IOC::BlockInjection and Catalyst::IOC::ConstructorInjection
125      - Create COMPONENTSingleton life cycle
126
127  11) we build the service too early, causing the COMPONENT method to be
128      called early, breaking components which build other components (e.g.
129      Model::DBIC::Schema).
130
131  12) root service has a very ambiguous name - maybe root_dir?
132
133  13) should _get_component_type_name (in Catalyst::IOC::Container) exist?
134
135  14) Test cases for extending the container in an application.
136      - Using the sugar added in the previous item
137      - Test when Model::Foo depends_on Model::Bar
138      - Test for component Foo => ( lifecycle => 'Singleton', class => 'My::External::Class', dependencies => { config => depends_on("config") } )
139      - Fix ^^ so that you can get your component's namespaced config nicely.
140
141  15) Tests for using the container outside of Catalyst
142      - Custom container which adds some (very simple) services which are initialized from
143        the application config file (note plain services, not components)
144      - Depend on (and test) these inside Catalyst
145      - Test loading container outside Catalyst, and these services working
146      - Test Catalyst / MyApp is not loaded
147
148     16) _build_(request|response)_constructor_args need replicating in
149         this branch.
150
151 ### Next steps
152
153   - Push the config built in the container back up onto the app
154
155   - Find a better way to make path_to work. Current fix is in
156     Catalyst::IOC::Container, subs build_home_service, build_root_service.
157
158   - Improve validation on the 'component' methods in  Catalyst::IOC
159     (check the type of the component, etc)
160
161   - Thigs to test:
162     - Imports getting the importing package in Catalyst::IOC
163     - Back compat for Catalyst.pm moved methods (locate_components)
164     - Custom container
165       - writing some tests which verify that the models you think should be
166         there are there, and that they received their dependencies as arguments
167       - i.e. Model::Bar should get params { foo => $model_foo } when being
168         constructed, etc
169       - Need to test that if you have a standard component Frotz
170         and a customized component Fnar, and Fnar depends on Frotz
171       - And yeah, some tests that the customised components actually work via
172         $c->model('Foo'), and that COMPONENT is called (or not called)
173         as appropiate and that ACCEPT_CONTEXT is called (or not) as appropriate
174
175
176 #### Extending my app, notes
177
178 Basically try to implement something like this (starting out without the sugar!), and see how it breaks
179 and what needs to be done to fix it!
180
181 ##### Eventual syntax
182
183 package MyApp::Container;
184 use Catalyst::IOC;
185
186     container $self, as {
187             container model => as {
188                 component Foo => (); # As per default!
189                 component Bar => (dependencies => ['/model/Foo']); # Magic!
190                 component Baz => ( lifecycle => 'InstancePerContext );
191                 component Quux => ( lifecycle => 'Singleton' ); # ACCEPT_CONTEXT not called
192                 # Catalyst::Model::Adaptor example
193                 component Fnar => ( lifecycle => 'Singleton', class => 'My::External::Class', dependencies => { config => depends_on('config')} );
194                 #                                                                                               ^^ FIXME - gets whole config, not Model::Foo
195                 #                                                                                                  There should be a 'nice' way to get the 'standard' config
196             };
197             # Note - implementation of BB may need to be changed to support making sure existing
198             # services actually get overridden. not sure how the default container behaves when doing that
199             # above code would build the constructor injection as it currently does,
200             # defaulting to the class name in the right namespace as declared by the surrounding container
201             # as well as adding using the catalyst-specific service class
202     };
203
204 1;