Understanding Signals parameter and Command injection

Vicker Leung's Avatar

Vicker Leung

27 Nov, 2013 07:53 AM

Hi there,

I am a newbie who was using Swiz and trying to learn Robotlegs. Currently I am struggling with Signals and Command injection and would like someone to guide me through.

I saw some example application that have a Signal containing 2 string parameters.

== Signal constructor == super (String, String); // param1 and param2

I don't understand why the command knows which one to inject with even they are simply base classes.

== Command class ==

[Inject] public var param1:String; [Inject] public var param2:String;

Is that simply based on the ordering of the [Inject] tag?
If that's the case, does it mean that if I have other inject above such as services, the injection will fail?

== Command class ==

[Inject] public var service:SomeService; [Inject] public var param1:String; [Inject] public var param2:String;

Cheers
Vicker

  1. Support Staff 1 Posted by creynders on 27 Nov, 2013 08:16 AM

    creynders's Avatar

    I'd strongly recommend against passing primitive types directly as a
    payload in a signal, you should _always_ wrap them in a value object.

    As to your question, if I'm not mistaken the injector should actually
    inject the same value twice, i.e. it should pass the last argument passed
    to the signal constructor into both `param1` and `param2` members of the
    command, since behind the scenes it simply iterates over all the values and
    maps them to the injector like this:

    injector.map(payloadClasses[i]).toValue(payloadValues[i])

    which means it will first map the first signal constructor argument to
    String and then overwrite that mapping with the second signal constructor
    argument.

  2. Support Staff 2 Posted by creynders on 27 Nov, 2013 08:23 AM

    creynders's Avatar

    Forgot a part:

    The command can receive the signal payload values in two ways:

    1/ into Inject-tagged members (as in your above example)
    2/ as parameters to the execute function.

    In 1/ the order of the signal values doesn't matter at all. E.g:

    function MySignal(signalFoo:IFoo, signalBar:IBar)
    

    will correctly be injected into

    [Inject]
    public var commandBar: IBar;
    
    [Inject]
    public var commandFoo: IFoo;
    

    However. In 2/ the order is of importance

    public function execute(parameterFoo: IFoo, parameterBar: IBar):void
    

    won't throw an error, but this will:

    public function execute(parameterBar: IBar, parameterFoo: IFoo):void
    
  3. 3 Posted by Vicker Leung on 27 Nov, 2013 08:58 AM

    Vicker Leung's Avatar

    Thanks for the detailed explanation. Now I get a better picture.

    Indeed injecting value object is more reasonable though I just worry if only a simple string is needed, wrapping it up as a value object seems too much.

  4. Support Staff 4 Posted by creynders on 30 Nov, 2013 08:26 AM

    creynders's Avatar

    It's not overkill. I try to wrap all my primitive types into VO's for sake of clarity, readability, better debugging. A primitive type tells you nothing about the intent/type of the data.
    When dealing with primitive types you need to rely on member and variable names to know what kind of data your dealing with.
    E.g.

    function login(username:String, password:String):void
    

    both parameters are strings and you infer what they represent through the parameter names. However, for instance the password is pretty opaque. Is it encrypted? Unencrypted? Unencrypted, yet salted? Etc. Obviously this is information you could start storing in the parameter name: unencPassword, encPassword, etc. but this means that you'll be sprinkling conversion specific metadata throughout your code. It's harder to refactor and easier to mess up. (For instance: a method first received an unencrypted password, gets refactored, but you forgot to change the parameter name)
    However if you use a Password VO it can store both values, the encrypted and unencrypted, and the client code can use the value it needs with very little rewriting.

    There's another benefit: many times you'll be comparing data and VO's help you centralize that logic instead of repeating it at several places.
    E.g. you need to compare usernames. At first you wrote a simple equality check whether two usernames are the same, but later on you realize you forgot that usernames should be case insensitive. Probably you'll be adding the additional check in a number of places, while if you'd had a Username VO with a isEqual method to begin with, you'd be modifying the isEqual method and that's it.

  5. Ondina D.F. closed this discussion on 23 Dec, 2013 09:27 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