robotlegs bootstrap with reading config file

iamable's Avatar

iamable

04 Aug, 2014 10:00 AM

Hello I am more or less new to robotlegs and I am trying to get a complete bootstrap running.
for this I had some help from other sides.

I'm using a statemachine and within the bootstrap command defining this:

var fsmInjector:FSMInjector = new FSMInjector( AppConfigStateConstants.FSM );
            var stateMachine:StateMachine = new StateMachine(eventDispatcher);
            
            //map the commands for the state machine.
            //all states in the machine are mapped to a specific command
            // that is triggered in order
            commandMap.mapEvent(AppConfigStateConstants.CONFIGURE_SERVICES, ConfigureServicesCommand, StateEvent, true);
            commandMap.mapEvent( AppConfigStateConstants.CONFIGURE_VIEWS, ConfigureViewsCommand, StateEvent, true );
            commandMap.mapEvent( AppConfigStateConstants.CONFIGURE_MODELS,ConfigureModelsCommand, StateEvent, true );
            commandMap.mapEvent( AppConfigStateConstants.CONFIGURE_COMMANDS, ConfigureCommandsCommand, StateEvent, true );
            commandMap.mapEvent( AppConfigStateConstants.FAIL,ConfigurationFailedCommand, StateEvent, true );
            
            //injecting the state machine into the FSMInjector
            fsmInjector.inject(stateMachine);
            
            //start the state machine
            eventDispatcher.dispatchEvent( new StateEvent(StateEvent.ACTION, AppConfigStateConstants.STARTED));

within the ConfigureServicesCommand I would like to load a config file and read some values and store them in one of my models.
How would you do that and how can I ensure all data were read and stored before running the next ConfigureCommand?

Thanks for your help

  1. 1 Posted by iamable on 04 Aug, 2014 11:27 AM

    iamable's Avatar

    I found some posts where is mentioned commands should not handle asynchronous data events.
    so maybe its better to delegate this to the service?

    so I just trigger reading the config file and after reading completely the service itself will dispatch the next event for bootstrapping?

    does that make sense?

  2. Support Staff 2 Posted by Ondina D.F. on 04 Aug, 2014 11:35 AM

    Ondina D.F.'s Avatar

    Hello,

    within the ConfigureServicesCommand I would like to load a config file and read some values and store them in one of my models.

    I would create a Service class, that would take care of the loading of your config files.
    Then, from within ConfigureServicesCommand, where you also mapped the above mentioned service, you dispatch a custom event triggering a command (that was already mapped in a ConfigureCommandsCommand), which can access your service. When the service is done, it dispatches a StateEvent:

    eventDispatcher.dispatchEvent( new StateEvent(StateEvent.ACTION, AppConfigStateConstants.CONFIGURE_SERVICES_COMPLETE));

    and the statemachine can continue with the other config commands.

    So, instead of dispatching CONFIGURE_SERVICES_COMPLETE from ConfigureServicesCommand, you dispatch it from the service, when the loading process has finished.

    Of course, you can define more appropriate SM constants for the StateEvent that represent the loading of config files, if you wish.

    Hope that helps.

    Ondina

  3. Support Staff 3 Posted by Ondina D.F. on 04 Aug, 2014 11:36 AM

    Ondina D.F.'s Avatar

    Oh, now I'm seeing your second post.
    Yes, that's correct.

  4. 4 Posted by iamable on 04 Aug, 2014 12:44 PM

    iamable's Avatar

    Thank you.
    And how is it possible to write the key-value-pairs into the model?
    Is there a possibility to merge those values to my models properties?
    Its because the names are similar

  5. Support Staff 5 Posted by Ondina D.F. on 04 Aug, 2014 01:29 PM

    Ondina D.F.'s Avatar

    You're welcome.
    I guess, you should change the order of your mappings, models first, then commands, then services. When the service has finished loading the configs, it dispatches a custom event to trigger a command, which populates the model with the results and the command or the model dispatches CONFIGURE_SERVICES_COMPLETE or LOADING_CONFIGS_COMPLETE or something similar.

    But in this case, where you have almost all the mappings already, with the exception of views/mediators, I think, it might be easier to change the logic a bit. Load the config files first after the mapping process has finished. Then a StateEvent CONFIGURATION_COMPLETE, dispatched from the above mentioned command or model, could let your application know, when it is safe to add your views or other classes, so that everything is ready for interactions with the framework and/or the user. Maybe your use case doesn't allow that kind of workflow, so you'll have to find what's best for you. Since you're using the StateMachine, you can control/manage the order of operations as you wish :)

  6. 6 Posted by iamable on 04 Aug, 2014 01:54 PM

    iamable's Avatar

    OK I think there was a missunderstanding maybe caused by my bad english...

    My question was how to map the values coming from the INI loader service to the variables in the model?

    for example in the model there is a value private value:int = 4 and in the .ini is a value=10.
    How can I pass that ini data to the model?

    In addition I have a further question:
    Whats going wrong here:

    public class MainContext extends Context implements IContext
        {
            public function MainContext(contextView:DisplayObjectContainer)
            {
                super(contextView);
            }
            override public function startup():void
            {
                commandMap.mapEvent(ContextEvent.STARTUP, BootstrapApplicationCommand, Context, true);

            dispatchEvent(new ContextEvent(ContextEvent.STARTUP));
        }
    }</code>
    
    
    
    

    BootstrapApplicationCommand is never executed from startup (startup is executed)

  7. Support Staff 7 Posted by Ondina D.F. on 04 Aug, 2014 02:28 PM

    Ondina D.F.'s Avatar

    OK I think there was a missunderstanding maybe cause by my bad english...

    Ah, don't you worry about your English. My English is not much better than yours ;)

    There is a little typo in your code:
    commandMap.mapEvent(ContextEvent.STARTUP, BootstrapApplicationCommand, Context, true);

    The third parameter is eventClass and it should be ContextEvent, not Context!
    This is correct:
    commandMap.mapEvent( ContextEvent.STARTUP, BootstrapApplicationCommand, ContextEvent, true );

    Now, the other part of your question is not very clear to me, but not because of your English. In your other post you talked about "merging" the values? What do you mean by that?
    Can't you just assign the value from your config file like this:

    model.someProperty = value;

    The event dispatched by the service can carry a payload. This payload can be a single value, or an array or any other collection, or a VO. Are you asking how to send such a payload through an event?

  8. 8 Posted by iamable on 06 Aug, 2014 06:23 AM

    iamable's Avatar

    Great thanks.
    Everything is working pretty well now.

    One last question:

    while bootstrapping within the ConfigureServicesCommand I'm defining the singleton for a SocketConnect class.

    'injector.mapSingleton(FPKConnect);'

    how can I directly call the constructor after that?

    Normally in other classes the first injection calls the constructor. But I want to call it while bootstrap.

  9. Support Staff 9 Posted by Ondina D.F. on 06 Aug, 2014 06:34 AM

    Ondina D.F.'s Avatar

    Glad to hear it worked out.

    how can I directly call the constructor after that?

    injector.mapSingletonOf(ISomeService, SomeService);
    var service: ISomeService = injector.getInstance(ISomeService);
    service.connect();
    
  10. 10 Posted by iamable on 06 Aug, 2014 07:05 AM

    iamable's Avatar

    perfect. Thank you
    Why using mapSingletonOf and this interface?

  11. Support Staff 11 Posted by Ondina D.F. on 06 Aug, 2014 10:39 AM

    Ondina D.F.'s Avatar

    Oh my, that's a subject for an entire book in and of itself;)
    In fact, the topic has been widely covered in several books, articles and/or discussions, already. I won't be able to give you an exhaustive explanation, so I'll just point out some of the benefits of using an interface that are coming to mind right now, in no particular order. I'm pretty sure that a lot of what I'm going to say isn't new to you. Sorry if it will sound too didactic:)

    It's been considered a good practice to code against interfaces, not only when using a framework like robotlegs.

    One can start with Wikipedia's definition of 'interface':
    'In object-oriented programming, a protocol or interface is a common means for unrelated objects to communicate with each other. These are definitions of methods and values which the objects agree upon in order to cooperate.'

    and of 'design by contract':
    'Design by contract (DbC), also known as contract programming, programming by contract and design-by-contract programming, is an approach for designing software. It prescribes that software designers should define formal, precise and verifiable interface specifications for software components, which extend the ordinary definition of abstract data types with preconditions, postconditions and invariants. These specifications are referred to as "contracts", in accordance with a conceptual metaphor with the conditions and obligations of business contracts.'

    • since an interface is often defined as a contractual obligation to implement certain methods or properties, one benefit is that you get immediate compiler errors if your classes implementing the interface don't adhere to the contract. Also, it makes sure that people on your team, or yourself, are implementing the class correctly. It helps you 'remember' the role of a class.

    • interfaces make up the structure of your project. Just by looking at interfaces you get a pretty accurate idea of what's going on in an application. No need to dig deep into code details.

    • clients of your code don't need to worry about implementation details. Best example: robotlegs framework. You don't need to know the inner work of the MediatorMap, you just access its methods through IMediatorMap

    • this kind of API contract ensures the classes are well encapsulated

    • multiple classes can implement the same interface. Thus, one concrete implementation can be switched for another one, if need be. Say, XMLLoadingService and SQLLoadingService implement ILoadingService. So, the 'contractual obligations' in ILoadingService might be fulfilled by XMLLoadingService or SQLLoadingService. If you map ILoadingService to XMLLoadingService, you'll get the concrete XMLLoadingService and of course, if you map ILoadingService to SQLLoadingService, you'll get the concrete SQLLoadingService. - keyword: plug-and-play

    • a class can implement multiple interfaces. Interfaces can extend one or more other interfaces. That gives you a lot of flexibility in defining different behaviours for a class

    • switching the implementation makes it possible to 'mock' classes like Services or Models, before you have real data or concrete implementations of those classes. That's good for testing or for providing dependencies in the early stages of designing your application. If a class needs SomeModel as a dependency, but you don't even know how the implementation of SomeModel looks like at this point in time, you can use a DummyModel implementing the ISomeModel, and inject the needy class with an empty ISomeModel, just to keep it quite and content;)

    • using mapSingletonOf makes sure that your code is not dependent on concrete classes, which means you've achieved the desired goal of decoupling (and reusability to some extent)

    • in a modular application you can build a library containing interfaces shared by different modules, where the implementation varies from module to module

    • programming to interfaces instead of implementations introduces stability and uniformity in code

    For the omitted benefits of using interfaces, please consult the interwebz ;)

    Keywords: plug-and-play, decoupling, encapsulation, mock, testability, behaviour, design by contract, flexibility

    [EDIT] It occurred to me that I forgot to mention that the notions of "encapsulation" and "information hiding" are often used interchangeably. I agree with those who think that there is a difference between the two.

    I've read a paper a while back, that I found to be very interesting.
    It takes a different approach than is usually taken when discussing the topic of interfaces. I thought it was worth sharing it, even with programmers who already know a lot about interfaces.
    I'll give you the name of the document, so you can search it yourself, if you wish to read it:
    Revisiting information hiding: reflections on classical and nonclassical modularity

    Here an excerpt from the paper:
    "Information hiding is to distinguish the concrete implementation of a software component and its more abstract interface, so that details of the implementation are hidden behind the interface. This supports modular reasoning and independent evolution of the “hidden parts” of a component . If developers have carefully chosen to hide those parts ‘most likely to change’, most changes have only local effects: The interfaces act as a kind of firewall that prevents the propagation of change."

  12. Support Staff 12 Posted by Ondina D.F. on 09 Aug, 2014 08:25 AM

    Ondina D.F.'s Avatar

    I guess this is resolved. I'm going to close the thread for now. You can re-open it at any time, if need be.

  13. Ondina D.F. closed this discussion on 09 Aug, 2014 08:25 AM.

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