tag:robotlegs.tenderapp.com,2009-10-18:/discussions/robotlegs-2/6915-best-practice-for-sharing-mappings-between-contextsRobotlegs: Discussion 2013-10-04T15:53:48Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/291307282013-10-01T16:55:19Z2013-10-01T16:55:21ZBest practice for sharing mappings between contexts<div><p>Hi.</p>
<p>New to the forum. This may be more of a swift suspenders query.
Please let me know if there is a better location for this
question.</p>
<p>Im working on a modular app where the application shell defines
a parent context that has mappings shared between modules and
individual module contexts for local data. The module mediators
need to have both values from the parent and local context injected
into them. What is the standard practice / idiom for achieving
this?</p>
<p>Thanks in advance for any advice or pointers to existing
documentation on the subject,<br>
Tod</p></div>tod.antillatag:robotlegs.tenderapp.com,2009-10-18:Comment/291307282013-10-01T17:47:39Z2013-10-01T17:47:39ZBest practice for sharing mappings between contexts<div><p>Hey Tod,</p>
<p>It's getting late here, where I live. I'll answer your question
tomorrow, if you don't get any help until then.</p>
<p>Which version of robotlegs are you using, 1 or 2? There are
different modular utilities for each version.</p>
<p>In case you didn't find them already, here are some links to
modular examples:</p>
<p>rl1:<br>
<a href=
"http://joelhooks.com/2010/05/02/modular-robotlegs/">http://joelhooks.com/2010/05/02/modular-robotlegs/</a><br>
<a href=
"http://knowledge.robotlegs.org/discussions/resources/33-links-to-robotlegs-resources-examples-tutorials">
http://knowledge.robotlegs.org/discussions/resources/33-links-to-ro...</a>
(look for modular)</p>
<p>rl2:<br>
<a href=
"https://github.com/dotdotcommadot/ModularRL">https://github.com/dotdotcommadot/ModularRL</a></p>
<p><a href=
"https://github.com/Ondina/robotlegs-bender-modular-air">https://github.com/Ondina/robotlegs-bender-modular-air</a>
(work in progress)</p>
<p>Till tomorrow,<br>
Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/291307282013-10-01T17:51:35Z2013-10-01T21:01:40ZBest practice for sharing mappings between contexts<div><p>Thanks Ondina,</p>
<p>I'm using RL2, I'll browse your links.</p>
<p>Update:</p>
<p>It looks the RL2 modularity extension primarily deals with event
mapping, whereas I'm looking to share mappings in context
injectors. Assuming I have access to the parent context while
configuring a child context I would like to do something like :</p>
<p>childContext.injector.inheritFrom(parentContext.injector)</p>
<p>It appears I have to remap and inject items individually:</p>
<p>var api: IParentAPI =
parentContext.injector.getInstance(IParentAPI);<br>
childContext.injector.map(IParentAPI).toValue(api);</p>
<p>However I am having issues obtaining instances of parent context
interfaces. It may have something to do with the application
domain, but so far in other cases I have been able to avoid class
definition conflicts if I create class references for all the
shared classes in the parent application. I guess a work around
would be creating strongly typed interfaces for the modules and
manually setting parent instances there.</p></div>tod.antillatag:robotlegs.tenderapp.com,2009-10-18:Comment/291307282013-10-02T09:01:56Z2013-10-02T09:01:56ZBest practice for sharing mappings between contexts<div><p>First, let's take a look at the ModularityExtension's
constructor:</p>
<pre>
<code>public function ModularityExtension(inherit:Boolean = true, expose:Boolean = true)</code>
</pre>
<p>If you use the MVCSBundle, the ModularityExtension will be
installed with the default values: the context inherits from a
parent context all the dependencies defined there, and will expose
its own mappings to its children.</p>
<p>Now, let's create a ShellModel with a mapping like this one
:</p>
<p>injector.map(ShellModel).asSingleton();</p>
<p><strong>[1]</strong> ShellModel mapped <strong>only</strong> in
the ShellContext</p>
<p><strong>[2]</strong> ShellModel mapped in the ShellContext
<strong>and</strong> in ModuleContext</p>
<p>We inject ShellModel into a Shell class and into a Module
class.</p>
<p><strong>[1]</strong></p>
<p>The module will inherit the mappings from shell. If you change
shellModel.someProperty inside a shell class before creating the
module, module's ShellModel will reflect those changes.</p>
<p><strong>[2]</strong></p>
<p>The mappings inside of the ModuleContext will override shell's
mappings. The Module will get its own instance of ShellModel.</p>
<p>Of course, you can map the model as an interface, which is btw.
a recommended practice:<br>
injector.map(ISomeModel).toSingleton(ShellModel);<br>
and inject the interface wherever you need it, and it will work
just the same.</p>
<p>If you need parent's injector, for some reason, you can access
it like this:</p>
<p>injector.parent or context.injector.parent</p>
<p>Does that answer your question?</p>
<p>Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/291307282013-10-02T13:30:14Z2013-10-02T13:30:14ZBest practice for sharing mappings between contexts<div><p>Im using the MVCS bundle, and I've tried explicitly
instantiating the<br>
ModularityExtension as well, but the child context is still
throwing errors<br>
that it doesn't have mappings that parent context has. However if I
call<br>
childContext.configure(ParentConfig) where ParentConfig has already
been<br>
configured in the parent context, ParentConfig.configure doesn't
execute<br>
which perhaps means ParentConfig is being managed by<br>
the ModularityExtension. Are there any caveats to the creation of
the child<br>
context which might vary the behavior of the ModularityExtension?
Ill build<br>
from the RL source so I can put break points in and create a
simpler test<br>
example to see what I might be doing wrong.</p>
<p>Thanks,<br>
Tod</p></div>tod.antillatag:robotlegs.tenderapp.com,2009-10-18:Comment/291307282013-10-02T13:39:01Z2013-10-02T13:39:01ZBest practice for sharing mappings between contexts<div><p>You shouldn't use ParentConfig in your Modules. Each context
should have its own config with its own contextView.<br>
Would it be possible for you to attach a simple app which
reproduces the issues and where I can see your setup for the Shell
and Modules' configs?<br>
Or to paste all relevant code?</p>
<p>I can assure you, that, when the contexts are configured
correctly, the mappings from the shell context will be inherited by
the child contexts.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/291307282013-10-02T14:42:25Z2013-10-02T14:42:25ZBest practice for sharing mappings between contexts<div><p>I've attached an extremely simple example (AIR project) with 2
contexts, a parent and a child context. The ShellMainView adds
SomeView, which is just a simple component and not a Flex
Module.</p>
<p>ISomeModel is mapped inside Shell's context, and then injected
into ShellMainMediator and SomeMediator.<br>
You can play around with the mappings inside the parent's and
child's context, to see what happens.</p>
<p>I injected ISomeModel into mediators, just to keep it simple!!
As you probably know, injecting models into mediators is a disputed
practice ;)</p>
<p>Hopefully, my example will help you.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/291307282013-10-02T17:21:55Z2013-10-02T17:27:02ZBest practice for sharing mappings between contexts<div><p>Thanks much Ondina for your prompt and detailed responses.</p>
<p>Working up from a smaller test app I found that some mappings
that were not being inherited were manual injections in non view
mediated objects - which makes sense ( a disputed practice :) I now
have things running again but now that you've introduced me to the
options of the ModularityExtension I'm considering a different
approach.</p>
<p>Perhaps overriding the defaults to ensure the parent context is
not inherited is a safer way of allowing flexible, reusable
configuration across modules. When you mentioned that you shouldn't
use ParentConfig in your Modules I understand the case for that,
however one the great thing s about RL2 is creating custom bundles
and configs that can be reused. We have rather large component
libraries with complex configs that need to be shared by multiple
modules. I'm hoping to achieve a drop in functionality by using
local contexts in the following manner:
localContext.install(CustomBundle); where CustomBundle might be
initialized by more than one team member working on different
modules and the runtime wont produce vigilance errors about
duplicate mappings because the module context is isolated from the
shared application context. I hope this a valid approach for
sharing complex components across modules, I'm open to suggestions
if there is a more canonical idiom.</p>
<p>Thanks again,<br>
Tod</p></div>tod.antillatag:robotlegs.tenderapp.com,2009-10-18:Comment/291307282013-10-02T17:56:06Z2013-10-02T17:56:06ZBest practice for sharing mappings between contexts<div><p>You're welcome, Tod:)<br>
It's late here (again), so I'll address your questions about a
shared custom bundle tomorrow.<br>
Have you seen the attached example?</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/291307282013-10-02T18:30:54Z2013-10-02T18:30:54ZBest practice for sharing mappings between contexts<div><p>Yep, the attached example worked fine. Now Im expanding it to
test<br>
configuration options by installing components from other flex
library<br>
projects before deciding on the strategy for the existing apps
going<br>
forward. (a sprawling set of deprecated Flex 2.0 and cairngorm[ugh]
libs<br>
and applications that we are porting to RL2)</p></div>tod.antillatag:robotlegs.tenderapp.com,2009-10-18:Comment/291307282013-10-03T12:55:52Z2013-10-03T12:55:52ZBest practice for sharing mappings between contexts<div><p>I made another example this morning, based on the first one.
There are 4 child-contexts: Alfa, Beta, Charlie, and Zulu, with
different setups.<br>
In the 'commons' folder there are 3 shared bundles/configs:
sharedOne, sharedTwo and sharedThree. Btw, the names of all the
folders and/or classes are not optimal, but without a concrete use
case, it's difficult to find descriptive names. I hope that they
aren't too confusing, though.</p>
<p>sharedOne contains a custom MVCS bundle, MVCSBundleOne, with a
new ModularityExtension(true, false), that inherits dependencies
from a parent context.</p>
<p>sharedTwo contains MVCSBundleTwo, with a new
ModularityExtension(false, false), that does <strong>not</strong>
inherit any dependencies from a parent context.</p>
<p>sharedThree contains MVCSBundleThree, with a new
ModularityExtension(false, true), that does <strong>not</strong>
inherit any dependencies from a parent context, but exposes
dependencies to children.</p>
<p>RobotlegsContextOne uses MVCSBundleOne and RobotlegsContextTwo
uses MVCSBundleTwo.</p>
<ul>
<li>
<p>AlfaView uses its own AlfaRobotlegsContext, where it installs
MVCSBundleOne and maps AlfaView to AlfaMediator in
AlfaMediatorsConfig. It will inherit the mapping for ISomeModel
from shell. In AlfaRobotlegsContext you can use the setting that
are commented out instead of the ones I used, and you'll see what
happens.</p>
</li>
<li>
<p>BetaView is similar to AlfaView. It uses the shared
MVCSBundleOne.</p>
</li>
<li>
<p>CharlieView - CharlieRobotlegsContext uses MVCSBundleTwo, not
inheriting from parent, and the shared ModelsConfig. But since
there are no mappings for CharlieMediator, it won't be created, so
the mapping of the Model is useless.</p>
</li>
<li>
<p>ZuluView with ZuluRobotlegsContext and an MVCSBundleThree,
simply adds SomeView from the common folder (which could be
extracted into a library as well). SomeView is instantiating its
own context (RobotlegsContextOne or RobotlegsContextTwo)-see the
comments in SomeView. Also, see what happens if you comment out the
mapping inside ModelsConfig.</p>
</li>
</ul>
<p>You can play around with the different settings until you get
dizzy;)</p>
<p>Conclusion: it is possible to share a custom bundle and also
configs classes for contexts with an identical setup. If a context
needs some special or additional configuration, I'd prefer to let
it have its own config classes, like Alfa and Beta.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/291307282013-10-04T14:43:52Z2013-10-04T14:43:52ZBest practice for sharing mappings between contexts<div><p>Well done! Thanks for combinatorially exhausting the rest of the
non<br>
default settings of the Modularity extension(nice color coding).
With this<br>
kind of flexibility I could see runtime composition of components
similar<br>
to what many entity system game frameworks use. Consider my mind
and this<br>
issue a' splode:) Now for some kind of FSM integration so modules
can<br>
receive and request generic state changes from the shell without
being<br>
tightly coupled to it.</p>
<p>Have a great weekend.</p></div>tod.antillatag:robotlegs.tenderapp.com,2009-10-18:Comment/291307282013-10-04T15:52:47Z2013-10-04T15:52:47ZBest practice for sharing mappings between contexts<div><p>Thanks!<br>
I hope you'll be able to reclaim your mind soon and that your
weekend will be great as well :)</p></div>Ondina D.F.