A new Parsley Extension: The DynamicServices tag

I just pushed a new Parsley extension project to GitHub – support for the <DynamicService /> tag.

Typically in a project, I like to structure my services layers pretty cleanly – for each service I would declare the following:

  • An interface which defines the services contract
  • A concrete implementation of the interface, which abstracts away the RemoteObject
  • A stub implementation of the interface, for testing when the services layer is unavailable

For example, a simple EchoService might look a little something like this:

// IEchoDelegate.as
public interface IEchoDelegate
{
     function echoMessage(source:String):AsyncToken;
}

// EchoDelegate.as
public class EchoDelegate
{
   [Inject]
   public function service:RemoteObject;

   public function echoMessage(source:String):AsyncToken
   {
      return service.echoMessage(source);
   }
}

Here, you can see the concrete delegate is really just boiler-plate code.  It’s pretty repetitive, and while I find lots of value in the pattern, the actual implementation can be a bore.

So, I put together a Parsley extension to generate these delegates on the fly.

Here’s an example:

<?xml version="1.0" encoding="utf-8"?>
<parsley:Objects>
   <fx:Declarations>
      <services:DynamicService type="{IEchoService}" endpoint="http://localhost:8080/testdrive/messagebroker/amf" destination="echoService" />
   </fx:Declarations>
</parsley:Objects>

This definition combines the Interface and the remote object defininition in the context. An implementation of the interface is generated on-the-fly at runtime, and is available to be injected into classes as required.

Eg:

// EchoCommand.as
	public class EchoCommand
	{
		[Inject]
		public var service:IEchoService;

		public function execute(message:EchoMessage):AsyncToken
		{
			return service.echo(message.source);
		}

		public function result(result:String):void
		{
			trace("Received from the server:" + result);
		}
	}

Source

The source for this is available now on github.  There’s also a demo project available here

A word of warning

Under the covers, this extension makes use of the ASCommons-Bytecode library to build an implementation of the interface.

Unfortunately, this dynamic goodness is not free, and incurs a one-off cost at startup when the ByteCode library parses the bytecode of the swf into memory.  As a result, you’ll notice that Parsley takes a little longer to intitialize than you might be used to.  This is a tradeoff that must be considered before using this approach.

Advertisements
Tagged ,

3 thoughts on “A new Parsley Extension: The DynamicServices tag

  1. Nice post. I hate writing those boiler plate classes for things like delegates.
    Does this approach make it any easier to write your stub implementations or do you still have to do that from scratch?
    How do you switch between stub services and real services?

    • Marty Pitt says:

      Hey Giles

      You could argue that by default, it makes stubbing easier because it frees up time from the sameness of boiler plate implementations to focus on the different-ness of writing stubs.

      However, I intend on using this project as a stepping stone to writing an implementation of Martin Fowler’s Self Initializing Fake, which should make the whole process of stubbing significantly easier.

      I’ve started tinkering, and will throw up a working example once I get it going.

  2. nikhil says:

    Hi Marty,
    My question is not related to above post , With HTML5 becoming so popular do you think flex is good option for career ?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: