MethodInvoker

(This tag must be placed inside an <EventHandlers> tag, <MessageHandlers> tag or <Injectors> tag)

MethodInvoker is one of the most used tags. When placed inside a EventHandlers tag and the list of handlers is executed, it will create an object of the class specified in the "generator" attribute. It will then call the function specified in the "method" attribute on the newly created object. You can pass arguments to this function that come from a variety of sources, such as the event itself, a server result object, or any other value. Unless you specify cache="none", this object instance will be "cached" and not instantiated again.

Example:

<MethodInvoker
   generator="ClassNameToInstantiate"
   method="methodToExecute"
   arguments="{['argument1', 'argument2']}" />

The above example would be the same as doing the following in ActionScript code:

var myWorker:ClassNameToInstantiate = new ClassNameToInstantiate();
myWorker.methodToExecute('argument1', 'argument2');

The main difference is that in the case of the MethodInvoker, the object is created and the function executed whenever the list of handlers is run and in the order specified in the list.

Note: To call static methods, methods on a singleton object, or on an object that has been created elsewhere, use the InlineInvoker tag instead.

Attributes

generator

required

The generator attribute specifies what class should be instantiated and run.

Suppose you have a class called "MyWorker" in the package com.yourdomain.business. You can specify a complete path to com.yourdomain.business.MyWorker:

<MethodInvoker
   generator="com.yourdomain.business.MyWorker"
   method="methodToExecute"
   arguments="{['argument1', 'argument2']}"/>

Generally you may want to use a binding to specify the class name. Assuming you have an import statement like this in your Event Map:

import com.yourdomain.business.MyWorker;

or simply:

import com.yourdomain.business.*;

You can then instantiate your object using bindings:

<MethodInvoker
   generator="{MyWorker}"
   method="methodToExecute"
   arguments="{['argument1', 'argument2']}"/>

The advantage of using this syntax is that if you are using Flex Builder, you can press the command key (Mac) or the Ctrl key (Windows) and click on the generator class (MyWorker in the example) and it will take you to the class definition.

method

The method attribute specifies what function to call on the created object. If your class MyWorker contains a function called doWork(), you would then write:

<MethodInvoker
   generator="{MyWorker}"
   method="doWork"
/>

arguments

If the function in your class has arguments, you can pass them via the "arguments" attribute. Suppose your doWork function has the following signature:

public function doWork(name:String, value:Number)

then you can pass those arguments as follows:

<MethodInvoker
   generator="{MyWorker}"
   method="doWork"
   arguments="{['Tom', 36]}"/>

Note that the arguments attribute expects an array. Besides passing literal values, you can pass values coming different sources. See Passing Arguments

cache

either "global", "inherit", "local" or "none"

The cache attribute lets you specify whether this newly created object should be kept live so that the next time an instance of this class is requested, this already created object is returned instead.

For example, say you have two sets of event handlers that want to use the same instance of an object. Since the default value for this attribute is "inherit", it will do that by default. On the other hand, if you wanted to have two different instances, then you must set this attribute to "none".

The value "inherit" will globally cache the object in a normal EventMap and it will locallly cache the object in a LocalEventMap. If you want to cache globally in a LocalEventMap so that the object can be accessed from other event maps, set the value to "global".

<EventHandlers type="myEventType">

   <MethodInvoker
      generator="{MyWorker}" method="doWork"
      cache="false" />

      
</EventHandlers>

<EventHandlers type="myOtherEventType">

   <MethodInvoker
   generator="{MyWorker}" method="doDifferentWork"
   cache="false" />

   
</EventHandlers>

constructorArguments

Array

If the constructor of you class requires arguments, you can pass them via the "constructorArguments" attribute. Suppose your constructor has the following signature:

public function MyWorker(name:String, value:Number)

then instantiating the class as follows will work:

<MethodInvoker generator="{MyWorker}"
   constructorArguments="{['Tom', 36]}"
   method="doWork"/>

See Passing Arguments

Inner tags

Properties

You can add properties to your object by using the Properties tag inside the MethodInvoker tag. These properties will be set before calling the function specified in the "method" attribute, so you can be sure that those properties will be available when the function is executed. These properties must be public.

Suppose you are creating an instance of a ShippingCalculator class. This class has a property called weightFactor and flatFee. In order to set those two properties, you can use the <Properties> inner tag. As attributes of the Properties tag, you can specify the names of your properties and set the values of those properties by setting the value of those attributes as follows:

<MethodInvoker
   generator="{ShippingCalculator}"
   method="calculateShipping" .... >


      <Properties weightFactor="0.5" flatFee="3" />

</MethodInvoker>

Besides specifying literal values, you can assign values coming from the event that triggered the handlers:

<MethodInvoker
   generator="{ShippingCalculator}"
   method="calculateShipping" .... >


      <Properties weightFactor="{event.factor}" flatFee="{event.fee}" />

</MethodInvoker>

This assumes that the original event contained a factor property and a fee property.

If this MethodInvoker tag is inside a <resultHandlers> tag that originated from one of the service invoker tags, you can also pass values coming from the server result:

<RemoteObjectInvoker .....service attributes....>

   <resultHandlers>
   
      <MethodInvoker
         generator="{ShippingCalculator}"
         method="calculateShipping" .... >

      
            <Properties weightFactor="{resultObject.factor}" flatFee="{resultObject.fee}" />
      
      </MethodInvoker>
      
   </resultHandlers>

</RemoteObjectInvoker>

This assumes the server returned an object that contained a factor property and a fee property.

If this MethodInvoker tag is inside an <faultHandlers> tag that originated from one of the service builder tags, you can also pass values coming from the server fault. This comes in handy when you want to handle possible server errors.

<RemoteObjectInvoker .....service attributes....>

   <faultHandlers>
   
      <MethodInvoker
         generator="{MyErrorHandler}"
         method="handleShippingError" .... >

      
            <Properties myErrorProperty="{fault.faultDetail}" />
      
      </MethodInvoker>
      
   </faultHandlers>

</RemoteObjectInvoker>

You can also use the complete resultObject, fault or data as a property depending on what your event properties are.

For example, if the server returned a number with the value of the flat fee, you would be able to set the property "flatFee" with the server result:

<MethodInvoker
   generator="{ShippingCalculator}"
   method="calculateShipping" .... >


      <Properties flatFee="{resultObject}" />

</MethodInvoker>

You can use the service fault:

<MethodInvoker
   generator="{MyErrorHandler}"
   method="handleShippingError" .... >


      <Properties error="{fault}" />

</MethodInvoker>

You can also use the sequence data. The data property must be of type Object.

<MethodInvoker
   generator="{ShippingCalculator}"
   method="calculateShipping" .... >


      <Properties myProperty="{data}" />

</MethodInvoker>

Finally, you can use the lastReturn

<MethodInvoker
   generator="{ShippingCalculator}"
   method="calculateShipping" .... >


      <Properties myProperty="{lastReturn}" />

</MethodInvoker>

13 responses

  1. I think the MethodInvoker tag should have an instance attribute so that you can handle the caching for yourself. It just seems like that would be a more flexible solution. Say you have several EventMaps how are they going to share a model? What if you need multiple instances of the same model? Say you have an interface like firefox where each tab you want a new Document model. You want that tab to bind to a specific instance of a model.
  2. Charlie,
    We actually had that in previous versions. In the current version, that functionality has been transferred to the InlineInvoker tag.

    If you have several event maps, they would all share the same model if you specify cache="true", which is the default value.

    The example that you give about a Multiple Document Interface would require more work, but it is possible to achieve. Most likely, there would be a "Tab Manager" that would take care of passing/storing the corresponding document to the tabs (instead of trying to access the specific model from the event map).
  3. Hi,

    Let's presume, I've a class and it's constructor needs a parameter, how can I use the methodinvoker in this case?

    i.e.

    var repo:IRepo = new DjangoRepo("http://localhost:8000";);
    repo.getMedia( ... )

    do I have set a setter for the host parameter?

    regards,
    Viktor
  4. key on SmartObject is supposed to be sourceKey?
  5. yikulju,
    Sorry for the late reply. MethodInvoker also has a constructorArguments attribute that you can use to pass parameters to the constructor. See ObjectBuilder, which has more documentation on that. I'll add the documentation for that here too.

    steptan,
    That's right, thanks for the correction.
  6. I don't quite understand about what is sequence data. So Is there anybody can help me?

    You can also use the sequence data. The data property must be of type Object.
    <MethodInvoker
    generator="{ShippingCalculator}"
    method="calculateShipping" .... >

    <Properties myProperty="{data}" />

    </MethodInvoker>
  7. I have an issue where I need my generator to be more dynamic. I have something like this:

    <InlineInvoker method="{ getMethodInvokerGenerator }"/>      
    <MethodInvoker generator="{lastReturn}" method="methodtoCall" arguments="{argument }"/>

    I have also tried:
    <MethodInvoker generator="{SomeClass}" method="{ getMethodInvokerGenerator }"/>      
    <MethodInvoker generator="{lastReturn}" method="methodToCall" arguments="{argument }"/>

    Both methods give me an error:

    Type Coercion failed: cannot convert com.asfusion.mate.core::[email protected] to

    How can I make the generator class more dynamic so that I can set it in a function and use the lastreturn value?

    Thanks in advance for any help.
  8. Hi Luis, you can do that either with Properties or PropertySetter, the following example is using Properties tag.

    <MethodInvoker generator="{SomeClass}" method="{ getMethodInvokerGenerator }"/>
    <MethodInvoker method="methodToCall" arguments="{argument }">
    <Properties generator="{lastReturn}"/>
    </MethodInvoker>
  9. Thanks for the response Nahuel. I tried your suggestion, however, that gives me a Mate error "Generator not found". I'm not so sure how to use the ProperySetter tag to accomplished the desired functionality.
  10. Sorry Luis, you are right that is not possible, you can set all the other attributes in the tag but not that one. If you really need that feature you can create an extension. Or add as a feature request on uservoice.
  11. lets say that you have a MethodInvoker and the method that it invokes returns and object , i was wondering if there was a good way to pass that return value through another method invoker or something... any help would be appreciated.
  12. Matt,
    See Using lastReturn
  13. Thanks Laura...

Comments now closed