26 Replies Latest reply: Jan 22, 2010 11:08 AM by Jeff Battershall RSS

    Cairngorm 3 & Dynamic Modules

    Jeff Battershall Community Member

      I'm excited about the new module implementation, but I have some questions about the way it's getting implemented in Cairngorm 3 so far.  It would seem that the way InsyncContext is architected, the modules are hard coded in the app.  The way I've implemented modules in the past was to make them completely data-driven, so I can make the available modules user profile-driven. 

       

      I'm interested in anyone's thoughts on how this could be done with Cairngorm 3.  Maybe some sort of Factory class that provides a new ParsleyModuleDescriptor with passed parameters for the module URL, etc? 

       

      Jeff

        • 1. Re: Cairngorm 3 & Dynamic Modules
          Tom Sugden Community Member

          Hi Jeff,

           

          That's a good question and I think modules are a good candidate for runtime configuration. We've also seen the requirement you mention, where different users are entitled to access different modules. Also, it can be desirable to release new modules into production without needing to redeploy the shell application that loads them.

           

          So how could this be implemented? Well both Spring ActionScript and Parsley provide a means of configuring a context at runtime from an XML file. With both frameworks this system is commonly used for configuring the Flex logging framework, but the same mechanism could be used for configuring module descriptors. What is needed is a class for describing the module and a component for loading and rendering it.

           

          Re. the Cairngorm module library, it's early days. This is one of the more experimental parts of Cairngorm and its design is very much up for debate. The intention is to provide some features not included in the Flex SDK, such as:

           

          • Abstraction of the loading process, so that modules, compiled stylesheets, sub-applications and other asynchronous loading processes can be handled in the same way.
          • Support for progress and error states that display while the module is loading and if an error occurs.
          • Runtime configuration of modules through declarative descriptors, placed in XML or MXML (your requirement).
          • Lazy loading of modules in response to messages.

           

          At the same time, features of the standard Flex ModuleLoader shouldn't be lost, such as the ability to declare multiple instances of the same module at different parts of the UI.

           

          Do these requirements resonate with you? Do you have thoughts on how you'd like to see them solved? Have you solved them before? It would be nice to stay as close to convention as possible.

           

          Best,

          Tom

          • 2. Re: Cairngorm 3 & Dynamic Modules
            Jeff Battershall Community Member

            Thanks Tom,

             

            The way I solved this previously was via a LoadModule event, which was

            derived from the profile downloaded for the logged in user. This was based

            on a simple "there can be only one" module of a given type.  The module was

            loaded into a ViewStack and as part of its instantiation, loaded necessary

            data assets. The issue I ran into as the unloading of the module.  Some

            modules would load/unload with no memory leaks a some wouldn't.  I spent

            quite a bit of time with the profiler trying to figure out why. Binding

            would seem to be a possible liability as when using quick and dirty MXML

            binding, the references were hard.

             

            I was very excited to read the Parsley docs about modules and contexts. If

            the context that the module is relying on is destroyed on unload, that would

            seem to address the issues with the module not unloading cleanly, so long as

            the view is bound to model objects with weak references.

             

            In the case of Cairngorm and Parsley, injection should be used instead, but

            the question becomes how to perform that injection in ActionScript vs. MXML.

            That's what leads me toward a global Module factory class that would deliver

            a fully configured module based upon a descriptor and add that to the

            appropriate landmark in the view hierarchy.

             

            Jeff

            • 3. Re: Cairngorm 3 & Dynamic Modules
              Jeff Battershall Community Member

              I decided to throw caution to the winds and attempt to port an existing application over to CG3 with modules - but with the modules hard-coded like they are in the sample CG3 app.  I'm treating this as sort of a tutorial to get up to speed with CG3 and Parsley.  I've been able to get the modules to load correctly but run aground on commands.  Events fired in the module's context don't seem to want to communicate to Comands declared in the same context.  Basically the messaging 'sub-system' isn't working and I haven't been able to figure out what I'm doing wrong.

               

              Any advice appreciated.

               

              Jeff

              • 4. Re: Cairngorm 3 & Dynamic Modules
                Alex Uhlmann Community Member

                Are you using parsley 2.1 and the command and module libs from trunk? 

                If not, please try that.

                 

                Sent from my iPhone

                • 5. Re: Cairngorm 3 & Dynamic Modules
                  Jeff Battershall Community Member

                  Thanks Alex,

                   

                  I believe that I've got all the dependencies downloaded from the trunk and in the build path:

                   

                  Module

                  Navigation

                  Integration

                  IntegrationRPC

                  Task

                  parsley-complete-flex3-2.1.0.swc

                  spicelib-complete-flex-2.1.0.swc

                   

                  Here's the PM that is dispatching the event:

                   

                   

                   

                   

                  ilc.modules.timeline.presentation

                  {

                   

                  import flash.events.EventDispatcher;

                   

                  import ilc.modules.timeline.GetDecadesEvent;

                   

                  [

                  Event(name="getDecades", type="ilc.modules.timeline.GetDecadesEvent")]

                  [ManagedEvents(

                  "getDecades")]

                   

                  public class TimelinePM extends EventDispatcher

                  {

                   

                   

                  public function TimelinePM()

                  {

                  getDecades();

                  }

                   

                   

                  public function getDecades():void

                  {

                  dispatchEvent(

                   

                  new GetDecadesEvent());

                  }

                  }

                  }

                   

                  Here's the Command class:

                   

                  package

                   

                   

                  ilc.modules.timeline.application

                  {

                   

                  import ilc.modules.timeline.GetDecadesEvent;

                   

                  import ilc.modules.timeline.domain.Decades;

                   

                   

                  import mx.collections.ArrayCollection;

                   

                  import mx.rpc.AsyncToken;

                   

                  import mx.rpc.events.FaultEvent;

                   

                  import mx.rpc.events.ResultEvent;

                   

                  import mx.rpc.remoting.mxml.RemoteObject;

                   

                   

                  public class GetDecadesCommand

                  {

                   

                  public function GetDecadesCommand()

                  {

                   

                  }

                   

                  [MessageDispatcher]

                   

                  public var dispatcher:Function;

                   

                  [Inject]

                   

                  public var decades:Decades;

                   

                  [Inject(id=

                  'remoteService')]

                   

                  public var service:RemoteObject;

                   

                  [Command]

                   

                  public function execute(event:GetDecadesEvent):AsyncToken

                  {

                   

                  trace('getting decades');

                   

                  return service.getDecades() as AsyncToken;

                  }

                   

                  [CommandResult(selector=

                  "getDecades")]

                   

                  public function serviceResult(event:ResultEvent):void

                  {

                  decades.decades =

                  new ArrayCollection(event.result as Array);

                  }

                   

                  [CommandFault(selector=

                  "getDecades")]

                   

                  public function showError(fault:FaultEvent):void

                  {

                   

                  trace(fault.toString());

                   

                  }

                   

                  }

                  }

                   

                  Do you see anything obvious?

                   

                  Jeff

                   

                   

                   

                   

                  • 6. Re: Cairngorm 3 & Dynamic Modules
                    Jeff Battershall Community Member

                    I'm beginning to think there's something up with the way I'm creating the child contexts - as my PM that should have been injected into one of the views in the heirarchy, but it's null.   It should be as simple as creating a new config,mxml in the module itself - should it not?

                     

                    Jeff

                    • 7. Re: Cairngorm 3 & Dynamic Modules
                      Alex Uhlmann Community Member

                      You also need to wire your view to Parsley with i.e. a configureIOC event or the Configure tag. Check out the Parsley docs for that. Have you checked out the InsyncModularExtended projects for an example using the C3 module library? There's also a tutorial on that in our guidelines.

                      • 8. Re: Cairngorm 3 & Dynamic Modules
                        Tom Sugden Community Member

                        I think that messaging is normally scoped to a context hierarchy, so in order for a message sent in the context of a module to be received by handlers in another context, those contexts must be within a hierarchy. In other words, when you build the context for your module, Parsley needs to be able to find the parent context too. It tries to do this automatically with Parsley 2.1, but in some cases it cannot succeed, so you need to specify the parent context manually via the FlexContextBuilder.build() method.

                        • 9. Re: Cairngorm 3 & Dynamic Modules
                          Jeff Battershall Community Member

                          Thanks Tom (and Alex),

                           

                          I'll check the Parsley docs on how to refer to the parent context.  In the case of modules it would seem to me that the model objects would want to live exclusively in the context of the module - am I right?

                           

                          What I am noticing in the case of my module is that the context is available at the module view heirarchy level but not available in any child views, even if I have included them in the context definition and have fired off the 'configureIOC' event from within the view.  In the app I am converting, the module contains another view which I am injecting my PM into, and the PM keeps coming back null.

                           

                          Even still, though, when I am firing my event which should result in command class getting executed in my module, the messaging does not appear to be working.

                           

                          Jeff

                          • 10. Re: Cairngorm 3 & Dynamic Modules
                            Tom Sugden Community Member

                            Maybe you're using the wrong view wiring event? In Parsley 2.0 it was called "configureIOC", but in Parsley 2.1 the ViewConfigurationEvent,CONFIGURE_VIEW is used, or the <Configure> tag.

                            • 11. Re: Cairngorm 3 & Dynamic Modules
                              Jeff Battershall Community Member

                              Tom,

                               

                              A further development: if I use the MessageHandler metatag instead of Command, it works (at least in the immediate context of the module).  Am I correct that the Command extensions are in the Integration.swc?  I checked out the integration libraries have referenced the Integration.swc from my test project. Is there another dependency that I'm missing?

                               

                              Jeff

                              • 12. Re: Cairngorm 3 & Dynamic Modules
                                Alex Uhlmann Community Member

                                Jeff,

                                 

                                please have a look into the InsyncModularExtended sample applications. They also use Commands, the IntegrationRPC library and show you how to set it up. It works there but I'd be interested if there's anything different in your scenario that would make the integration library fail. Maybe you're missing to initialize the integration RPC library in your entry level MXML. Check out the Insync samples. They have commands in the contacts module.

                                • 13. Re: Cairngorm 3 & Dynamic Modules
                                  Jeff Battershall Community Member

                                  Alex,

                                   

                                  I did not have the integration libs tag in my module - only at the top level of the app That was it!!!!!! - thank you and Tom for hanging in there on this.

                                   

                                  However, I'm still not getting my model injected into a view child of my module. I switched to ViewConfigurationEvent.CONFIGURE_VIEW to ensure that there was nothing up with my spelling but no, my child view still isn't getting injected with my model, even though I have the view in my context definition.

                                   

                                  Jeff

                                  • 14. Re: Cairngorm 3 & Dynamic Modules
                                    Jeff Battershall Community Member

                                    Tom, Alex,

                                     

                                    Although my understanding of C3 is progressing, it is far from what it should be.  The most frustrating part of this is getting the data retrieved by a Command back into the model.  It appears that the PM model that I might be injecting is not singleton or possibly may exist in more than one scope.  I've tried passing a reference to my target model in a Managed event, but so far no dice.  Almost makes me wish for a ModelLocator.

                                     

                                    Jeff

                                    • 15. Re: Cairngorm 3 & Dynamic Modules
                                      Alex Uhlmann Community Member

                                      Hi Jeff,

                                       

                                      Have you studied the Parsley developer manual for more overview? Also check if this could be causing different instances of your PM. Enable logging on Parsley to see if any message handler runtime errors have been thrown or use Parsley's MessageError tag.

                                      • 16. Re: Cairngorm 3 & Dynamic Modules
                                        Jeff Battershall Community Member

                                        Alex,

                                         

                                        I have been into the Parsley docs quite a bit.  Just gotta keep pushing until I fully assimilate the pattern of development.

                                         

                                        Jeff

                                        • 17. Re: Cairngorm 3 & Dynamic Modules
                                          Jeff Battershall Community Member

                                          Alex,

                                           

                                          I admit to being completely confused at this point.  I fire off a managed

                                          event which invokes a Command, which returns an array, everything seems to

                                          be fine, but the reference if the model object that's being updated is not

                                          the one I referred to.   It's almost as if the context and my normal Flex

                                          view aren't talking to each other.  It's like the context and view are in

                                          parallel universes.  And I still have the issue where subviews aren't

                                          getting processed by the context upon instantiation.

                                           

                                          I'm quite sure I am **** something wrong - I'm comparing my source code

                                          against the sample insync extended app and trying to identify where I've

                                          gone astray...

                                           

                                          Jeff

                                          • 18. Re: Cairngorm 3 & Dynamic Modules
                                            Alex Uhlmann Community Member

                                            Have you looked into the Parsley forum post I pointed out in my last post (discussion between Xavi and Jens). Your problem sounds familiar. Also, make sure you understand Parsley's messaging scope feature.

                                            • 19. Re: Cairngorm 3 & Dynamic Modules
                                              Jeff Battershall Community Member

                                              Alex, Tom,

                                               

                                              I'm making some incremental headway but it is slow going as I try to figure out whether the behavior I'm seeing is the result of my inexperience with Parsley or possible bugs in the framework itself.  Here's what I've been able to accomplish so far:

                                               

                                              I've got my shell app working with modules being loaded on demand - not dynamic modules mind you - but hard coded at this point. Works fine.

                                               

                                              I've also been able to get my Commands to send results back to the view - this works but things go awry when I have a subview to the module.  I can inject the child view, but the child view keeps getting added/removed/added into the context and my RPC calls are duplicated.  In the end, the bindings from my model to the child view's components don't get executed.

                                               

                                              Jeff

                                              • 20. Re: Cairngorm 3 & Dynamic Modules
                                                Alex Uhlmann Community Member

                                                Hi Jeff,

                                                 

                                                sorry but I have to repeat myself. Have you read the Parsley forum post between Xavi and Jens I pointed to above? There are also more threads on that topic in the Parsley forum if you search for it. Your problem sounds exactly like that. It's caused by multiple addedToStage events. There are workarounds.

                                                • 21. Re: Cairngorm 3 & Dynamic Modules
                                                  Alberto Alcaraz Community Member

                                                  UPDATED: Ok, doesn't mind. I just understand that you were simply meaning to put the tag <cairngorm:CairngormIntegrationLib /> inside the module.

                                                  Thanks anyway!!

                                                   

                                                   

                                                  Hi Jeff, I'm having the exact same problem in a project; if I change [Command] by [MessageHandler] it works correctly.

                                                   

                                                  The problem is that I have the integrationlib.swc added to the module. What do you mean with "I did not have the integration libs tag in my module"?

                                                   

                                                   

                                                  Thanks!

                                                  • 22. Re: Cairngorm 3 & Dynamic Modules
                                                    Jeff Battershall Community Member

                                                    Tom,

                                                     

                                                    I was wondering if you've been working on runtime module configuration and if there's been progress in that area.

                                                     

                                                    Jeff

                                                    • 23. Re: Cairngorm 3 & Dynamic Modules
                                                      Tom Sugden Community Member

                                                      Hi Jeff,

                                                       

                                                      I haven't had time to work on this library myself but have a few opinions about how it should change. It's being used on a few other Adobe projects, so I expect some improvements based on their experiences.

                                                       

                                                      I'd like the design to change in this way:

                                                       

                                                      1. Module loading abstracted by an IContent (or something) interface instead of overloading IModuleInfo. Then different implementations can be used for modules, modules with compiled CSS, or other configurations. Some projects need to use special authentication services before loading each module, so that kind of customization could be hidden behind the interface. Instances of these classes could be declared in MXML or XML config files, with the latter being suitable for dynamic modules.

                                                       

                                                      2. Change the ViewLoader component so it works for multiple instances of the same module, and so the behavior is more similar to ModuleLoader in Flex.

                                                       

                                                      3. Write a new stack container for modules, so that only a single loading-overlay and error-state child is present. If you place 10 ViewLoaders in a view stack, you end up with a loading overlay child for each module.

                                                       

                                                      Best,

                                                      Tom

                                                      • 24. Re: Cairngorm 3 & Dynamic Modules
                                                        Tom Sugden Community Member

                                                        Hi Jeff,

                                                         

                                                        Did you notice that commands have been incorporated into the Parsley 2.2 release candidate 2:

                                                         

                                                        http://www.spicefactory.org/parsley/download.php

                                                         

                                                        Jens Halm made some definite improvements over the implementation in Cairngorm 3, so I'd recommend having a look at those. The short-lived command objects are particularly nice. It looks like the Parsley 2.2 developer manual is still in progress, but a description of the new command features can be found here:

                                                         

                                                        http://www.spicefactory.org/parsley/docs/2.1/manual/roadmap.php#commands

                                                         

                                                        Best,

                                                        Tom

                                                        • 25. Re: Cairngorm 3 & Dynamic Modules
                                                          Jeff Battershall Community Member

                                                          Thanks, Tom.

                                                           

                                                          My particular use case is pretty darned simple - user profile maps to

                                                          available modules and navigation reflects this.  When navigated to for the

                                                          first time, the module is loaded into a view stack. In my app, there's only

                                                          area that loads modules.  So what we really have is a shell application with

                                                          modules loaded on demand.

                                                           

                                                          I guess my question is, would a simpler approach be more appropriate for my

                                                          app? Conceivably it could be as simple is sending a message that a certain

                                                          module should be loaded (with it's url, etc), and the selectedIndex of the

                                                          ViewStack changed accordingly.

                                                           

                                                          Jeff

                                                          • 26. Re: Cairngorm 3 & Dynamic Modules
                                                            Jeff Battershall Community Member

                                                            Tom,

                                                             

                                                            That looks great!  Nice collaboration between you and Jens! 

                                                             

                                                            Jeff