tag:robotlegs.tenderapp.com,2009-10-18:/discussions/problems/5816-modular-injection-mappingsRobotlegs: Discussion 2014-08-09T08:22:51Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-07-31T07:51:09Z2014-07-31T07:51:09ZModular Injection Mappings<div><p>Hello Tyler,</p>
<p>If you're using FlashBuilder, these answers might help you:</p>
<p><a href=
"http://knowledge.robotlegs.org/discussions/problems/336-1070-context-was-not-found#comment_8424814">
http://knowledge.robotlegs.org/discussions/problems/336-1070-contex...</a></p>
<p><a href=
"http://knowledge.robotlegs.org/discussions/problems/246-the-definition-of-base-class-context-was-not-found#comment_4836370">
http://knowledge.robotlegs.org/discussions/problems/246-the-definit...</a></p>
<p>Let me know whether that solved your problem or not.</p>
<p>For your information, you can download the latest version of
robotlegs 1, which is 1.5.2 from here:<br>
<a href=
"http://www.robotlegs.org/">http://www.robotlegs.org/</a></p>
<p>Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-07-31T12:08:59Z2014-07-31T12:09:02ZModular Injection Mappings<div><p>I've tried with Robotlegs 1.5.2, to no avail. It's not that it's
missing the classes, it's that it tries to satisfy the
"IMediatorMap" injection mapping and failing...</p></div>Tylertag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-07-31T12:14:12Z2014-07-31T14:18:47ZModular Injection Mappings<div><p>Ondina,</p>
<p>Thanks for the reply, but this is not my issue.</p>
<p>Everything builds and runs fine, but when the child module is
loaded it tries to satisfy the IMediatorMap injection mapping and
says that it is missing that mapping. Sometimes it will say
it’s missing the DisplayObjectContainer mapping.</p>
<h2><a name="" class="anchor" href="#"></a></h2>
<p>Tyler Padley</p>
<p>Solutions Architect | Leonardo<a href=
"http://www.leonardo.com/">http://www.leonardo.com/</a></p>
<p>T 416-272-5495 | <a href=
"mailto:tyler.padley@leonardo.com">tyler.padley@leonardo.com</a><a href="mailto:tyler.padley@leonardo.com">tyler.padley@leonardo.com</a></p>
<p>[<a href=
"http://www.leonardo.com/mkt/sig/2014/sig2014.jpg">http://www.leonardo.com/mkt/sig/2014/sig2014.jpg</a>]<a href="http://blog.leonardo.com/say-hello-to-leonardo/">http://blog.leonardo.com/say-hello-to-leonardo/</a></p></div>Tyler Padleytag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-07-31T13:47:18Z2014-07-31T13:47:18ZModular Injection Mappings<div><p>I've attached Joel's demo, using rl 1.5.2. It works fine on my
end. Try it out.</p>
<p>Are you compiling against the source instead of the swc? If so,
have a look at Metadata Stripping:<br>
<a href=
"https://github.com/robotlegs/robotlegs-framework/wiki/Common-Problems#metadata-stripping">
https://github.com/robotlegs/robotlegs-framework/wiki/Common-Proble...</a><br>
Are you keeping a reference to your context?</p>
<p>If you're compiling against the source, what version of
Swiftsuspenders are you using? It might be the one, where IInjector
is used instead of Injector?</p>
<p>If you can't find the cause of your issues after reading the
Common-Problems, the best thing to do is to attach a bare-bone
project that reproduces your issues, and I'd take a look at it,
later today.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-07-31T14:02:20Z2014-07-31T14:02:23ZModular Injection Mappings<div><p>I have the 1.5.2 RL and the 1.5.1 swift suspenders, but I've
also got the modular utility source, signal source and variant
source since I couldn't find swcs for them.</p>
<p>My context creation worked fine until I passed a separate
application domain in, so it's not getting the application domain
from ApplicationDomain.currentDomain anymore.</p></div>Tylertag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-07-31T14:17:37Z2014-07-31T14:17:37ZModular Injection Mappings<div><p>Well, as I said, it would be easier for me to help you, if I
could see the code:)<br>
You have lots of libraries there, that might not be compatible with
each other ( because they are old?). If you can't attach you app or
one that has all your libraries included, then try to use the
modularity utility without the extra libraries in a very simple
project and see how it goes. Is Joel's demo working for you?<br>
You might want to try Swiftsuspenders 1.6...<br>
If you want, I can make the discussion private, if you don't want
others to see your code. I'll download the app, then delete it, and
then make the discussion public again..</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-07-31T14:21:08Z2014-07-31T14:21:09ZModular Injection Mappings<div><p>I appreciate the help Ondina, but it's not a privacy thing, the
app and framework that we have in place is massive in scope.</p>
<p>Everything was working fine but we were running into memory
issues so we decided to load the modules into child application
domains. Once we realized we had to pass the child application
domain into the module context creation because
"getApplicationDomainFromContextView" wasn't working (there was no
loaderInfo object since we are using ModuleManager.getModule() to
load our modules.</p>
<p>So that cleared up the application domain errors we were
receiving, but now we get this error, in which it cannot satisfy an
injection mapping for "contextView", in the first loaded module's
Context. So the shell application context, in the main application
domain, is still fine. This error occurs when the first module is
loaded and that context is created with the child application
domain passed to it.</p></div>Tylertag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-07-31T14:22:52Z2014-07-31T14:22:53ZModular Injection Mappings<div><p>When I breakpoint in the context creation routine I can see the
injector and all of its parent mappings, including
DisplayObjectCOntainer and IMediatorMap, exist in the
parentInjector mappings collection. It seems that putting a break
point in makes it work, but running it in real time throws this
error every time.</p>
<p>Is there a race condition here?</p></div>Tylertag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-07-31T14:32:53Z2014-07-31T14:33:09ZModular Injection Mappings<div><blockquote>
<p>it's not a privacy thing, the app and framework that we have in
place is massive in scope.</p>
</blockquote>
<p>It's alright, Tyler.</p>
<p>I have to discontinue our discussion for now. I'll be back
later...</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-07-31T14:35:53Z2014-07-31T14:35:55ZModular Injection Mappings<div><p>Ok, I'm trying the keep metadata and 1.6 suggestions, I'll let
you know if they work.</p></div>Tylertag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-07-31T17:56:27Z2014-07-31T17:56:27ZModular Injection Mappings<div><p>Ok, I'm almost to the point of pulling my hair out over here....
I grabbed the swift 1.5.1 source to get into the hooks and see what
was happening. It's an intermittent race condition.</p>
<p>It seems that it failing in the getResponse method as it fails
to find the mapping in either the injector, or the m_injector, or
the parent... even though in my traces out in the context injector
creation indicates clearly that it does have the mapping... somehow
that's not getting passed in... but only intermittently...</p></div>Tylertag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-07-31T18:53:57Z2014-07-31T18:53:57ZModular Injection Mappings<div><blockquote>
<p>Ok, I'm almost to the point of pulling my hair out over
here..</p>
</blockquote>
<p>I'm sorry for you. It might be very frustrating. Taking a break
may be helpful:)</p>
<p>In the below linked discussion there is an example of a modular
app that you can download (Ondina_ModularExperiment_taketwo.zip
).<br>
Don't forget to add the modules and to set the compiler options
(metatdata...)<br>
You can use it to experiment with different settings in order to
reproduce your issue:</p>
<p><a href=
"http://knowledge.robotlegs.org/discussions/questions/1361-loading-modules#comment_21736290">
http://knowledge.robotlegs.org/discussions/questions/1361-loading-m...</a></p>
<p>I suspect there is something wrong with your libraries and maybe
with the way you're passing the applicationDomain, even though you
said you solved that one.</p>
<p>I won't be able to talk to you until tomorrow (it's 9 p.m. here
where I live).<br>
I wish you luck.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-07-31T18:56:56Z2014-07-31T18:57:04ZModular Injection Mappings<div><p>From what I'm seeing as I dig further, it's that an
InjectionConfig is created with a "null" request object, and this
is coming from the injector.getApplicationDomain().getDefinition()
result.</p>
<p>so there's something wrong with the definition.</p></div>Tylertag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-08-01T11:04:19Z2014-08-01T11:06:13ZModular Injection Mappings<div><p>Hmm, it is really hard to know what's going on in your project
without seeing at least some relevant code.<br>
The ApplicationDomain problem can occur under different
circumstances, and it is impossible for me to mention all possible
scenarios. There are several discussions on this topic on the
forum. Not sure if you've seen them..</p>
<p>A few things to consider (some of them were already mentioned
before) :</p>
<ul>
<li>
<p>simplify the use case - create your own mini-project or use the
one I've uploaded</p>
</li>
<li>
<p>use the modularity utility + robotlegs + swiftsuspenders without
any other libraries involved.</p>
</li>
<li>
<p>use a Swiftsuspender version that is compatible with the
modularity utility. In my example I used the source code for rl and
swiftsuspenders. I don't remember which versions they were, but
they work well together. It's been quite a while since I worked
with robotlegs v.1. Swiftsuspenders latest version is 2.1.0, but I
have no idea if it is compatible with the modular utility and rl
1.5. I'm currently using robotlegs 2' ModularityExtension, which by
the way is much easier to set up.</p>
</li>
<li>
<p>compiler arguments : -keep-as3-metadata+=Inject
-keep-as3-metadata+=PostConstruct</p>
</li>
<li>
<p>add the modules to the project in your IDE</p>
</li>
<li>
<p>make sure the module / moduleLoader is added to the stage</p>
</li>
<li>
<p>modules should implement IModule or an interface of your own
where you set the parent injector:</p>
</li>
</ul>
<pre>
<code>s:Module
implements="org.robotlegs.utilities.modular.core.IModule"</code>
</pre>
<ul>
<li>in the shell's context config:</li>
</ul>
<pre>
<code>override public function startup():void
{
viewMap.mapType(IModule);
}</code>
</pre>
<ul>
<li>
<p>the module's context implements IModuleContext: protected var
context:IModuleContext;</p>
</li>
<li>
<p>use this setter to provide the module with an injector. This
setter should initiate the context of the module via a
ModuleContext that accepts the injector through its constructor.
The ModuleContext will create a child injector:</p>
</li>
</ul>
<pre>
<code>protected var context:IModuleContext;
[Inject]
public function set parentInjector(value:IInjector):void
{
context = new SomeModuleContext(this, true, value, ApplicationDomain.currentDomain); }</code>
</pre>
<ul>
<li>if you use an ApplicationDomain, other than the currentDomain,
see if this workaround is solving your problem:</li>
</ul>
<pre>
<code>public function SomeModuleContext(contextView:DisplayObjectContainer=null, autoStartup:Boolean=true, parentInjector:IInjector=null, applicationDomain:ApplicationDomain=null)
{
var applicationDomain : ApplicationDomain =
(contextView["moduleFactory"] && contextView["moduleFactory"].info) ?
contextView["moduleFactory"].info().currentDomain :
contextView.loaderInfo.applicationDomain;
super(contextView, autoStartup, parentInjector, applicationDomain);
}</code>
</pre>
<ul>
<li>or find another way to inform the injector about the module's
ApplicationDomain</li>
</ul>
<p>You said you used ModuleManager? Like this?</p>
<pre>
<code>moduleInfo = ModuleManager.getModule("yourPath/SomeModule.swf");
moduleInfo.addEventListener(ModuleEvent.READY, onModuleReady);
moduleInfo.addEventListener(ModuleEvent.ERROR, onModuleError);
moduleInfo.load(ApplicationDomain.currentDomain, null, null, moduleFactory);</code>
</pre>
<p>What kind of errors do you get when you use
ApplicationDomain.currentDomain for your modules? Could you paste
the text of the error?</p>
<blockquote>
<p>It seems that putting a break point in makes it work, but
running it in real time throws this error every time. Is there a
race condition here?</p>
</blockquote>
<p>I have no idea what that could be. Which error are you referring
to? Are there some asynchronous processes going on? Maybe it's not
related to the modular utility at all?<br>
If you can't post some code (context initialization, moduleLoader
settings, how you set the applicationDomain, etc ) or describe the
workflow of loading your modules, I'm afraid that I can't really
help you.<br>
Please let me know if you found a solution.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-08-01T13:20:44Z2014-08-01T13:20:45ZModular Injection Mappings<div><p>Ondina,</p>
<p>Thanks for all of your assistance with this.... we were using
ModuleManager which meant that the loaderInfo object didn't exist.
The errors being thrown by swift suspenders and RL were caused by
the ApplicationDomain not having the definition, so there's
certainly an issue with the ApplicationDomain settings, and we
explored a few different options for loading modules into their own
application domain to no avail.</p>
<p>It seems that we can't really move forward on this without going
to RL 2.0 and higher version of flex as these issues are largely
framework related. Since the work involved to swap out our codebase
to meet these two requirements is so high we've decided to delay
that part as the codebase is already being partially converted to
Angular regardless.</p>
<p>Thanks again for your assistance,</p>
<p>Tyler</p></div>Tylertag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-08-02T11:17:24Z2014-08-02T11:17:24ZModular Injection Mappings<div><p>Hey Tyler,</p>
<p>I'm sorry to hear that you're giving up already.</p>
<p>I used my example to test the case of loading a module using
ModuleManager. It works well.</p>
<p>Here some code:</p>
<pre>
<code>private var moduleInfo:IModuleInfo;
private function onLoadModule():void
{
moduleInfo = ModuleManager.getModule("modules/someModules/SomeModule.swf");
moduleInfo.addEventListener(ModuleEvent.READY, onSomeModuleReady);
moduleInfo.load(new ApplicationDomain(ApplicationDomain.currentDomain), null, null, moduleFactory);
//or
//moduleInfo.load(ApplicationDomain.currentDomain, null, null, moduleFactory);
}</code>
</pre>
<ul>
<li>Option 1:</li>
</ul>
<p>Use ISomeModule to pass the applicationDomain to the Module's
contextView.</p>
<pre>
<code>public interface ISomeModule
{
function set applicationDomain(value:ApplicationDomain):void;
function set parentInjector(value:IInjector):void;
function dispose():void;
}</code>
</pre>
<p>In the Shell's context: viewMap.mapType(ISomeModule);</p>
<p>In the view loading the module you set the applicationDomain
using the interface:</p>
<pre>
<code>private function onSomeModuleReady(event:ModuleEvent):void
{
var iSomeModule:ISomeModule = moduleInfo.factory.create() as ISomeModule;
iSomeModule.applicationDomain = moduleInfo.factory.info().currentDomain;
modulesContainer.addElement(iSomeModule as IVisualElement);
}</code>
</pre>
<p>SomeModule implements="interfaces.ISomeModule"</p>
<pre>
<code>private var context:IModuleContext;
private var _applicationDomain:ApplicationDomain;
[Inject]
public function set parentInjector(value:IInjector):void
{
context = new SomeModuleContext( this, true, value, _applicationDomain);
}
public function set applicationDomain(value:ApplicationDomain):void
{
_applicationDomain = value;
}
public function dispose():void
{
context.dispose();
context = null;
}</code>
</pre>
<ul>
<li>Option 2: use moduleFactory to get loader's
applicationDomain</li>
</ul>
<pre>
<code>private function onSomeModuleReady(event:ModuleEvent):void
{
var module:IVisualElement = moduleInfo.factory.create() as IVisualElement;
modulesContainer.addElement(module);
}</code>
</pre>
<pre>
<code>[Inject]
public function set parentInjector(value:IInjector):void
{
context = new SomeModuleContext(this, true, value, this["moduleFactory"].info().currentDomain);
}</code>
</pre>
<p>I used rl 1.5.2 swc and the source of modular utility. I'll
attach them to this post.</p>
<p>So, that shows that it is possible to set the ApplicationDomain
even when ModuleManager is used instead of ModuleLoader. I wouldn't
blame robotlegs as a framework for the issues you've encountered,
but rather the combination of utilities or some special settings in
your project. You've tried so many combinations of libraries
already, so it is quite normal to get stuck, especially when the
different versions aren't compatible with each other. It's a pity
that there are no up-to-date libraries/utilities for robotlegs 1,
but that's a fact and we have to live with it:) Many of
rl-utilities authors or rl contributors aren't around
anymore...</p>
<p>So, I suggest you try one more time the combination of rl 1.5.2
swc and the source of the modular utility before giving up:) The
ApplicationDomain is an issue that many others have encountered in
the past, but it was and still is solvable.</p>
<p>Migrating a project from rl1 to rl2 is pretty easy. Let me know
if/when you need assistance with it. There are also some discussion
on that topic.</p>
<p>I'm sorry that I couldn't help you more.<br>
Anyway, I wish you luck with the Angular version of your app:)</p>
<p>Ondina</p>
<p>P.S. If you don't have any further questions, you can close the
discussion</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/339664102014-08-09T08:22:50Z2014-08-09T08:22:50ZModular Injection Mappings<div><p>I'm going to close this discussion. You can re-open it at any
time, if need be.</p></div>Ondina D.F.