tag:robotlegs.tenderapp.com,2009-10-18:/discussions/questions/20-subcontexts-in-a-large-modular-applicationRobotlegs: Discussion 2018-10-18T16:35:06Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/7074542009-12-10T18:06:18Z2009-12-10T18:06:22ZSubcontexts in a large, modular application<div><p>So here's the setup: I'm in the process of building a rather
large application which must be completely dynamic. RobotLegs has
been a huge help in keeping the app organized and testable, but I'm
having trouble determining what the best practice is for using
sub-contexts in an application, keeping in mind that those
sub-contexts may share some mappings with the original
super-context.</p>
<p>Example: The main context of the application uses mapSingletonOf
to control, say, the content model to one instance. When I create a
sub-context within this app, I could use mapSingletonOf again to
fill any dependencies within that context, but they would not be
filled with the same instance of the content model. Or think of
this in terms of a queue-loader service. There should ideally be
one queue loader instance to manage loading items within the app,
but every context would receive its own instance, thereby making
the queue loader useless.</p>
<p>I've been fighting with the best way to tackle this issue. I can
solve it by passing in the injector, reflector, and so on into a
custom sub-context class and assigning them before the default
SwiftSuspendersInjector et al are created, but this technique seems
far too clunky, and actually also demolishes the testability I've
grown so fond of with this framework.</p>
<p>I know in the best practices documentation you've mentioned that
it is possible to build modular applications with multiple
contexts, but the document is clearly concerned with a simpler sort
of application. Hopefully I'm missing an easier, cleaner way to
make data or services available safely in an application with
multiple contexts.</p>
<p>Has anyone else run into this problem? How did you end up
solving it?</p></div>Jeremy Ruppeltag:robotlegs.tenderapp.com,2009-10-18:Comment/7074542009-12-10T19:06:46Z2009-12-10T19:06:46ZSubcontexts in a large, modular application<div><p>Hey Jeremy,</p>
<p>if you're willing to use a beta version of SwiftSuspenders, you
might<br>
be interested in the newly added support for child injectors.
These<br>
can contain their own mappings, but in addition, they
automatically<br>
delegate all unknown injection requests to their parent
injector,<br>
enabling you to share mappings for all contexts while still<br>
configuring your contexts with their individual mappings.</p>
<p>As this feature of SwiftSuspenders is pretty new, there's no
currently<br>
no real documentation, but for some usage examples, you can see
the<br>
unit tests here:<br>
<a href=
"http://github.com/tschneidereit/SwiftSuspenders/blob/childinjectors/test/org/swiftsuspenders/ChildInjectorTests.as">
http://github.com/tschneidereit/SwiftSuspenders/blob/childinjectors...</a></p>
<p>To use the new version of SwiftSuspenders, you have to clone
the<br>
"childinjectors" branch from github and compile from source. I'll
try to put up a beta release of the swc in the coming days, so
using that<br>
should become much simpler.</p>
<p>cheers,<br>
till</p></div>Till Schneidereittag:robotlegs.tenderapp.com,2009-10-18:Comment/7074542009-12-10T19:53:34Z2009-12-10T19:53:34ZSubcontexts in a large, modular application<div><p>Hello, what kinda timeframe can we expect this kind of feature
to roll out of beta?</p>
<p>I would love to experiment with this feature and provide
feedback, but I would need proper documentation that I can
distribute to my team and also reference myself when they ask
questions.</p>
<p>Thanks and regards,<br>
Levi</p></div>levi.stropetag:robotlegs.tenderapp.com,2009-10-18:Comment/7074542009-12-10T21:59:45Z2009-12-10T21:59:45ZSubcontexts in a large, modular application<div><p>hey levi,</p>
<p>Honestly, I,m mostly waiting for some feedback before rolling it
out<br>
for real. but obviously, I should write some documentation for that
to<br>
happen.<br>
I do that tomorrow and think it should be up pretty quickly.
the<br>
feature is quite complex conceptually, but it has a really
minimal<br>
interface.</p></div>Till Schneidereittag:robotlegs.tenderapp.com,2009-10-18:Comment/7074542009-12-10T22:37:35Z2009-12-10T22:37:36ZSubcontexts in a large, modular application<div><p>Thanks for the quick response! Looks like this will be very
powerful indeed, exactly the idea I was looking for. I'm having a
tough time conceptualizing how it will be integrated smoothly into
RobotLegs though, especially since the Injector.createChildInjector
will not implement IInjector or be adapted. In fact, I'm still
trying to come up with an acceptable implementation of this within
RobotLegs' Contexts that doesn't couple the two libraries together
any more than they need to be. Have you had any luck talking this
great new feature over with Shaun?</p>
<p>Thanks again,</p>
<p>Jeremy</p></div>Jeremy Ruppeltag:robotlegs.tenderapp.com,2009-10-18:Comment/7074542009-12-10T22:49:43Z2009-12-10T22:49:43ZSubcontexts in a large, modular application<div><p>I'm not at my desk anymore so I can't give you an example right
now,<br>
but child injectors do implement IInjector and using them works<br>
without any changes to robotlegs.</p>
<p>will write documentation and an example tomorrow.</p></div>Till Schneidereittag:robotlegs.tenderapp.com,2009-10-18:Comment/7074542009-12-11T16:32:33Z2009-12-11T16:32:33ZSubcontexts in a large, modular application<div><p>I've added some documentation and example for using child
injectors to<br>
the SwiftSuspenders documentation:<br>
<a href=
"http://github.com/tschneidereit/SwiftSuspenders/blob/master/README.textile">
http://github.com/tschneidereit/SwiftSuspenders/blob/master/README....</a><br>
Also, I just added a build of the first 1.5 beta to the github
downloads:<br>
<a href=
"http://github.com/tschneidereit/SwiftSuspenders/downloads">http://github.com/tschneidereit/SwiftSuspenders/downloads</a></p>
<p>If you download this build and drop the contained swc into
your<br>
projects' libs folder, you should be able to use the child
injectors<br>
feature with the current Robotlegs release.</p>
<p>Looking back at what I wrote yesterday, I have to admit that
what I<br>
wrote about the child injectors implementing IInjector was
simply<br>
false, sorry about that! Alcohol and playing Poker just don't go
well<br>
with technical discussions ;)</p>
<p>Still, the actual behavior is no problem in practice: Just
inject the<br>
injector itself typed as Injector, not IInjector into your<br>
configuration command and use it directly:</p>
<p>//in your context: injector.mapValue(Injector, injector);</p>
<p>//in your startup command: [Inject] public var injector :
Injector;</p>
<p>Now to your use-case:<br>
for each subcontext, supply the main (or parent, if you're going
to<br>
have multiple levels of nesting) injector in the constructor.
Then<br>
create the child injector for the current context before
calling<br>
super, and you're done:</p>
<p>class ChildContext extends Context<br>
{</p>
<pre>
<code>public function ChildContext(contextView : DisplayObjectContainer,</code>
</pre>
<p>parentInjector : Injector)<br></p>
<pre>
<code>{
injector = parentInjector.createChildInjector();
super();
}</code>
</pre>
<p>}</p>
<p>Now, all mappings in the parent injector are still available in
the<br>
current context, but you can add additional mappings that are
specific<br>
to this context and don't affect the parent or any other
contexts.</p>
<p>I'll create an example of this over the next few days, but I
hope this<br>
helps you get started right now.</p>
<p>cheers,<br>
till</p></div>Till Schneidereittag:robotlegs.tenderapp.com,2009-10-18:Comment/7074542009-12-11T17:00:49Z2009-12-11T17:00:49ZSubcontexts in a large, modular application<div><p>Great!!!<br>
Actually the documentation is here (under childinjectors):<br>
<a href=
"http://github.com/tschneidereit/SwiftSuspenders/tree/childinjectors">
http://github.com/tschneidereit/SwiftSuspenders/tree/childinjectors</a></p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/7074542009-12-11T17:33:54Z2009-12-11T17:33:54ZSubcontexts in a large, modular application<div><p>Thanks again for the quick response, Till! Still, the same
problem exists where the ContextBase's definition of injector is
limited to IInjector, so the line...</p>
<p>injector = parentInjector.createChildInjector( );</p>
<p>...would still run into conflicts. I suspect that the changes
necessary to make this feature available within sub-contexts will
have to happen mostly in the RobotLegs side of things, namely:</p>
<ol>
<li>Have IInjector include the createChildInjector()
method.<br></li>
<li>We're in a little bit of a tricky spot here. We can either have
the SwiftSuspenders version of Injector implement IInjector
directly (tying the two libraries together perhaps too closely) or
expose getParentMapping, setParentInjector, etc as protected and
override them in the SwiftSuspendersInjector adapter to provide a
suitable Injector subclass when using createChildInjector.</li>
</ol>
<p>I think for the time being I may write a quick adapter to help
with assigning the child injector to the sub-context, but what are
your thoughts on the above?</p>
<p>Thanks again for the help on this issue, really appreciate
it.</p>
<p>Jeremy</p></div>Jeremy Ruppeltag:robotlegs.tenderapp.com,2009-10-18:Comment/7074542009-12-11T17:49:46Z2009-12-11T17:49:46ZSubcontexts in a large, modular application<div><p>@Ondina: Thanks for correcting that mistake!</p>
<p>@Jeremy: Serves me right for writing examples in emails instead
of testable projects - sorry for that!</p>
<p>You're completely right about the need to implement IInjector. I
think<br>
I have a workable approach in mind, I'll work on that over the<br>
weekend. As a quick outline, exposing Injector#setParentInjector as
a<br>
public method should enable using the injector created by the
Context,<br>
without changing anything in Robotlegs.</p>
<p>cheers,<br>
till</p></div>Till Schneidereittag:robotlegs.tenderapp.com,2009-10-18:Comment/7074542009-12-11T18:12:44Z2009-12-11T18:12:44ZSubcontexts in a large, modular application<div><p>@Jeremy: We have to be careful with what we put into RL's
IInjector interface - we need to support as many DI solutions as
possible. The idea is that IInjector represents what RL needs
access to in order to do it's job, but the app developer is free to
work directly with the underlying DI solution (in this case
SwiftSuspenders).</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/7074542009-12-11T18:16:25Z2009-12-11T18:16:25ZSubcontexts in a large, modular application<div><p>@Levi: it's a catch-22! Till needs someone to test out the Child
Injector stuff before he can roll it out (and before we roll that
into Robotlegs).</p>
<p>@Till: Sorry that I haven't had a chance to play with that stuff
yet - and it's looking like I won't have any time to do so for
quite a while :'<</p></div>Shaun Smithtag:robotlegs.tenderapp.com,2009-10-18:Comment/7074542009-12-11T18:46:43Z2009-12-11T18:46:43ZSubcontexts in a large, modular application<div><p>@Shaun: I'm more and more of the opinion that Robotlegs should
only support the most basic functionality of whatever DI solution
is used.<br>
Everything else should be used by adding a mapping to the
concrete<br>
injector implementation in the context and a matching injection in
a<br>
startup command. Adding IInjector#mapRule was a regrettable mistake
on<br>
my part.</p>
<p>No worries about not being able to play with child injectors - I
get<br>
that you have a day job ;)</p>
<p>@everyone: Shaun is completely right: I need feedback from real
world-usage before I can release a new version of SwiftSuspenders
that<br>
I can call "stable" with any confidence. I hope that releasing
a<br>
proper build of the beta version makes this easy enough.</p></div>Till Schneidereittag:robotlegs.tenderapp.com,2009-10-18:Comment/7074542009-12-11T19:20:53Z2009-12-11T19:20:53ZSubcontexts in a large, modular application<div><p>I understand the catch 22.</p>
<p>I do have a need for this in our project, I'll see if I can't
start implementing it.</p></div>levi.strope