When to use Extensions and when to use Commands?

mike.cann's Avatar

mike.cann

22 Oct, 2015 07:57 AM

Hi,

In RL2 we can add extensions to the context. Extensions typically add a mapping to the injector and hook into some context lifecycle event such as "beforeInitializing", "beforeDestroying" etc.

Now suppose I have some sort of custom error handler "MyCustomErrorHandler" that should be created when the app starts up and should have its "startListeningForErrors()" method call.

Should this class be created and mapped in an Extension and then hook into the context lifecycle events such as with MediatorMapExtension, StageCrawlerExtension, EventDispatcherExtension etc or should we use an event AppStartUpEvent.INIT mapped to a command AppInitCommand and then in there do the init logic for the MyCustomErrorHandler ?

Cheers,
Mike

  1. Support Staff 1 Posted by Ondina D.F. on 22 Oct, 2015 09:55 AM

    Ondina D.F.'s Avatar

    Do you want to create an extension for error handling?
    If the answer is no, I suggest to make the mapping in a config class ( a class implementing IConfig and having a public configure() method)

    You have a few options:

    a. map your ErrorHandler asSingleton with initializeImmediately set to true

    org.swiftsuspenders.mapping.InjectionMapping.asSingleton(initializeImmediately:Boolean=false):UnsealedMapping

    injector.map(ErrorHandler).asSingleton(true);
    

    In your ErrorHandler class annotate the startListeningForErrors() method with a [PostConstruct] metadata tag, so it starts automatically.

    b. add an afterInitializing method in the class where you create your context and instantiate the ErrorHandler like this:

    var errorHandler:ErrorHandler = context.injector.getOrCreateNewInstance(ErrorHandler);
    errorHandler.startListeningForErrors();
    

    c. within an afterInitializing method dispatch the event of your choice to trigger a command where you've injected an already mapped ErrorHandler and call its startListeningForErrors();
    That's only needed, if you have a special reason to do it in a command

    Would that work for you?

    When to use Extensions and when to use Commands?

    An Extension is like a utility or a library. Like the modular extension , logger extension, macrocommand, starling view map etc.
    Even in an Extension you don't need commands for mappings or instantiating of classes.

    Should this class be created and mapped in an Extension and then hook into the context lifecycle events such

    Yes, in case your intention is to create an Extension. The ErrorHandlerExtension class would take care of the mappings and hooking into the context's lifecycle, for example calling startListeningForErrors from within an afterInitializing handler.
    Of course, you need to pass
    ErrorHandlerExtension to the context.install() or to add it to the list of extensions in a custom MVCSBundle, for it to work as expected.

  2. Support Staff 2 Posted by Ondina D.F. on 22 Oct, 2015 10:09 AM

    Ondina D.F.'s Avatar

    I wanted to ask you, but then I forgot: How familiar are you already with rl2? Should I tell you more about config classes used for bootstrapping instead of rl1 commands? I'm asking because I don't want to offend an expert by being too didactic;)

  3. 3 Posted by mike.cann on 23 Oct, 2015 01:07 AM

    mike.cann's Avatar

    Hi Ondina,

    Thanks for such a long and detailed reply as always, you really are a ledgend!

    I am very familiar with RL1, used it on many projects for years. This is the first project with RL2 that is not a greenfields project, im trying to retroactively apply RL2 to it which is no easy task.

    My RL2 experience is limited to only a few small projects and this one. You dont need to explain all the basics tho I have a firm grasp of all that. My main difficultly was working out there "initialisation" logic goes in general.

    The ErrorHandler example I gave above was just an example. Its more of a generic question really.

    Assume the ErrorHandler is a generic bit of business logic that needs to be initiated with some runtime variables.

    I guess what you are saying is that if it isnt designed to be reused then dont put it in an Extension?

    Mike

  4. Support Staff 4 Posted by Ondina D.F. on 23 Oct, 2015 03:20 PM

    Ondina D.F.'s Avatar

    You're welcome, Mike. And thanks for what I think was a compliment;)

    You dont need to explain all the basics tho I have a firm grasp of all that.

    I'm sure you do have a firm grasp of all that!! And I wasn't going to explain all the basics, hehe. I know that you are an experienced developer in general and a robotlegs 1 user in particular, but I was not sure where you stood on rl2 and the differences between rl1 and rl2.

    My main difficultly was working out there "initialisation" logic goes in general.

    That's why I asked if you needed more details on config classes.

    I fact, I just wanted to mention these answers :
    http://knowledge.robotlegs.org/discussions/questions/2209-mediator-...
    http://knowledge.robotlegs.org/discussions/robotlegs-2/6370-baby-st...

    because there you can find a few tips on porting rl1 apps to rl2 and on how to tackle the initialisation of a rl context + mappings. Ignore them, if you already know all this stuff.

    I guess, the short answer should have been:

    Commands, are, as always, the place to handle application logic/behaviour/use cases, interaction with models and services, application's bootstrapping. You can continue using commands for bootstrapping, or replace them with configuration classes and use them like this:

    _context = new Context()
    .install(MVCSBundle)
    .configure(MediatorsConfig, ModelsConfig, ModelsConfig, SignalsConfig, CommandsConfig)
    .configure(new ContextView(_view); 
    // view == DisplayObjectContainer serving as contextView
    

    I guess what you are saying is that if it isnt designed to be reused then dont put it in an Extension

    Yes, reusable classes are good candidates for a library or utility. But, a library can be framework agnostic and as such it can be used in non-rl projects as well. Only if you want to integrate it into a robotlegs context, you create an extension for it. Extensions make the framework customizable. Extensions extend framework's capabilities, by adding new features or by integrating external utils. Extensions aren't meant to handle the business logic of an application. But, like with anything else in the robotlegs world, you are free to design your extensions for whatever purpose you need them for.

    The ErrorHandler example I gave above was just an example. Its more of a generic question really. Assume the ErrorHandler is a generic bit of business logic that needs to be initiated with some runtime variables.

    I think I answered that in the first part of my previous message. Or not?
    In general, afterInitializing would be a good place to start working with the already mapped classes of any kind. For example, you can dispatch an event to trigger a command, if you want to initiate some business logic...
    Tell me what exactly is still unclear, and the answers will be shorter:)
    Cheers
    Ondina

  5. 5 Posted by mike.cann on 28 Oct, 2015 08:51 AM

    mike.cann's Avatar

    Hi Ondina,

    Sorry for the late reply.

    Thanks again for that answer, its really appreciated. After thinking some more over the weekend and hacking at it the last few days I think I have a clearer understanding.

    I read those posts you linked and were a great help, thanks for that and thanks again for your continued support here :)

    Mike

  6. Support Staff 6 Posted by Ondina D.F. on 28 Oct, 2015 03:47 PM

    Ondina D.F.'s Avatar

    My pleasure!
    Thanks again for your kind words, Mike. Great motivational booster :)

    Ondina

  7. Ondina D.F. closed this discussion on 28 Oct, 2015 03:47 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