How to prevent injections into module (Loader with new ApplicationDomain) that is added to the shell's contextView?

pavel.fljot's Avatar

pavel.fljot

19 May, 2011 12:22 PM

In my case I load modules (SWFs, built with RL) into shell (built with RL) via Loader and new ApplicationDomain. I'm adding those modules to the shell's contextView, therefore shell's injector tries to inject something into them and fails (those classes have same names in terms of package, but actually they should be separated because of different application domains):

Exception fault: TypeError: Error #1034: Type Coercion failed: cannot convert mvcs::SignalBus @1a665ae1 to mvcs.SignalBus.

at org.swiftsuspenders.injectionpoints::PropertyInjectionPoint/applyInjection()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/injectionpoints/PropertyInjectionPoint.as:46]
at org.swiftsuspenders::Injector/injectInto()[/Users/tschneidereit/dev/swiftsuspenders/swiftsuspenders/src/org/swiftsuspenders/Injector.as:120]
at org.robotlegs.base::ViewMap/injectInto()[/Development/Projects/Robotlegs/robotlegs-framework/src/org/robotlegs/base/ViewMap.as:200]
at org.robotlegs.base::ViewMap/onViewAdded()[/Development/Projects/Robotlegs/robotlegs-framework/src/org/robotlegs/base/ViewMap.as:191]
at flash.display::DisplayObjectContainer/addChild()

....etc

As soon as I add module not to the contextView, but somewhere higher like stage — it works just fine. So the question is it possible to add modules to contextView but prevent injections into them? Or this will only work if I change all class names definition to unique (like "moduleName.mvcs.SignalBus", etc...)? Thanks!

  1. Support Staff 2 Posted by Stray on 25 May, 2011 08:10 AM

    Stray's Avatar

    Hi Pavel,

    did you get this figured out?

    One option would be to use the old-fashioned original version of the modular utilities - these don't use the child injectors, and don't inject from the shell to the loaded modules.

    Stray

  2. 3 Posted by pavel.fljot on 25 May, 2011 10:11 AM

    pavel.fljot's Avatar

    Nope, haven't figured out. I don't think modular utilities is something for me since I just load external SWFs in a new ApplicationDomain (it's not modules in RL concept, but just external RL-powered SWFs that should not be affected by shell's injector). So it's seems more like SwiftSuspenders question again.

  3. Support Staff 4 Posted by Stray on 25 May, 2011 10:39 AM

    Stray's Avatar

    Hi Pavel,

    if you add something to this contextView then the mediatorMap within that contextView will respond, and use the local injector, with the original appDomain, to try to fulfil the injections.

    Is there some way you can separate the contextViews? for example:

    stage view
        -> child container
                -> main context view
        -> child container
            -> loaded swf context view
    

    By container I just mean a sprite - doesn't have to be flex.

    Stray

  4. 5 Posted by pavel.fljot on 25 May, 2011 10:44 AM

    pavel.fljot's Avatar

    Yea, that's how I do now (as mentioned in the last paragraph of the original question), but doesn't seems like a perfect way.

  5. Support Staff 6 Posted by Stray on 25 May, 2011 10:49 AM

    Stray's Avatar

    Hi Pavel,

    well, you do have a multi-context app - and there are 3 solutions for that - one is the new modular utils, another is the old modular utils, and the 3rd is to keep your contexts totally separate - you've gone for the 3rd.

    I'll see if Till has any more thoughts about it, but I don't see a problem with what you're doing. The concept of 'contextView' means 'the view used for this context' - not just 'main view'. So it does have implications - which you've got a good work around for.

    Stray

  6. 7 Posted by pavel.fljot on 25 May, 2011 11:45 AM

    pavel.fljot's Avatar

    Stray, I still think it's an issue. Because I could really need to put my external swf somewhere into shell's context view, but still preserve it as a completely separate piece (not having any injections into it). So some (SOME!) sort of injector.preventFromInjection(view:DisplayObject) could make the trick... So unlike most "modular" topics I want to get non-modular behavior when loading the module =)
    Or maybe I miss something regarding modular utilities?

  7. 8 Posted by Stray on 25 May, 2011 12:00 PM

    Stray's Avatar

    I'm hoping Till will wade in here - he's much more aware of these kinds of intricacies than I am.

    The issue I think though is that you must have the same view class mapped in your shell as in your child views, yes? In the mediator?

    So - you have something like this in both the parent context and the loaded-swf context:

    mediatorMap.mapView(SomeView, SomeViewMediator); (or view map equivalent)

    The mediatorMap waits for ADDED_TO_STAGE events on the contextView - so if your child views are inside your contextView, and you add something to the stage, ALL context views that this element is inside of will try to create a mediator for it - because all those contextViews will fire the ADDED_TO_STAGE event. Perhaps? Unless I'm wrong about the way this event works in this scenario.

    If it is that the event is being fired in every parent in the chain, I'm not really sure there is anything that can be done about that in terms of the robotlegs side - there's no way for it interrogate the whole container (parent) chain to check for nested contextViews, because each mediatorMap is ignorant of the others, and a contextView is only an instance of DisplayObjectContainer, it has no special properties in terms of extending a class etc.

    So - how could any one contextView/mediatorMap know that it's not really supposed to mediate/map this class? Injection will only happen on mediators, commands and items marked for injection - so the example you cite (with the swf not having injections) wouldn't be a problem.

    Did I miss something? If I've got it wrong that you've got a view of the same type mapped to the mediatorMap in both your shell and your loaded swf then I could be way off here!

    Stray

  8. Support Staff 9 Posted by Till Schneidereit on 25 May, 2011 01:09 PM

    Till Schneidereit's Avatar

    Nope, you didn't miss anything: Your description of what's going on
    and why is spot on.

    The only thing I might add is that not only is this behavior hard to
    change from a technical point of view, it's also desirable in some
    cases.

    I've been thinking about how to optimize the case of nested
    contextViews for quite some time now and one idea I've had is to let
    mediatorMaps try to combine their ADDED_TO_STAGE/ REMOVED_FROM_STAGE
    listeners in the outermost contextView. That would allow for the
    creation of more complex behavior such as the innermost mediatorMap
    declaring a view as "handled" and thus stopping outer contexts from
    trying to map the view, too. I'm not sure if the advantages are worth
    the increased complexity, though.

  9. 10 Posted by pavel.fljot on 28 May, 2011 11:14 PM

    pavel.fljot's Avatar

    OK, here's proof of concept that actually worked as desired:

    ShellContext extends Context/SignalContext:

    override protected function get viewMap():IViewMap
    {
        return _viewMap ||= new ShellViewMap(contextView, injector);
    }
    

    ShellViewMap extends ViewMap:

    override protected function onViewAdded(e:Event):void
    {
        if (isValidView(e.target as DisplayObject))
        {
            super.onViewAdded(e);
        }
    }
    
    
    private function isValidView(target:DisplayObject):Boolean
    {
        var valid:Boolean = true;
        while (target.parent)
        {
            if (target is ModuleView)
            {
                return false;
            }
            target = target.parent;
        }
    
        return valid;
    }
    

    Not the most optimal & flexible code, but just to make an example. This allows me to add external RL module (loaded swf into new ApplicationDomain) into main contextView WITHOUT injecting anything into it, so two RL contexts becomes completely independent... well looks like =) haven't tested in all the possible ways. Now. Questions is — is it worth to add something into ModularUtilities (which is the last and popular one?) to implement this workflow?

  10. Support Staff 11 Posted by Till Schneidereit on 29 May, 2011 02:46 PM

    Till Schneidereit's Avatar

    At least in the implementation you give, this is bound to be
    excessively slow: The loop in isValidView will be invoked for each and
    every DisplayObject hitting the display list anywhere below the
    contextView. What you could do instead is to at least check if the
    ShellViewMap itself is even interested in the DisplayObject being
    added. If that is not the case, then you don't need to invoke
    isValidView at all.

    Other than that: Sure, this approach works. I'd be hesitant to add it
    to the ModularUtilities, though, as it is very specialized and only
    works for exactly you use-case, while disabling other use-cases such
    as views that should be handled by both the outer as well as the inner
    context.

    Adding flexible support for several nested contexts-scenarios is high
    on my list of priorities for RL 2, though.

  11. Stray closed this discussion on 10 Jun, 2011 03:54 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac