In Parsley, the injection framework is based around the view hierarchy, and Parsley relies on the build in event bubbling in Flash to configure view-components for IOC.

But what if you want to wire up a unit test with Parsley instead? The unit test does not sit in the view hierarchy so you can’t use the configure event or the inject tag I wrote about earlier in the week, because the configure events simply won’t bubble up to the view manager.

Fortunately there is an easy solution. The Parsley context contains a dynamic context, designed to wire up view components. This is also the right place to wire up the test cases.

Parsley makes this ever so easy, and to wire up your test case, all you need to do is configure the context and add the testcase to the dynamic context.

public class ContextAwareTestCase extends TestCase
{
public var contextClass : Class

override public function setUp() : void
{

var context : Context = FlexContextBuilder.build(contextClass);
context.createDynamicContext().addObject(this);

}

}

So as you can see, it’s very easy.  A few gotcha’s though – The context must be created in the setup method. This is because the lifecycle of a test case is different than a regular object, so if you try and create the context in the constructor, you’ll be in a world of pain.

You also want to create the context in the constructor to make sure that any objects you inject into the testcase are in a clean state – to avoid the old issue of testing singletons, where they change state once you’ve used them once.

This kind of thing can be useful to inject mock objects for remote objects for example, or if like me, you’re too lazy to programmatically define dependencies in your test cases;)

The current parsley implementation is using the configure event to configure views – This is fine for a small application, but the reflection performed on the view hierarchy is heavy so it’s not ideal for large projects where performance is an issue.

To address this issue on a project I worked on recently,we created a custom inject tag which will inject the dependencies without performing the full configure on the view component. This works well, because you don’t really want to be dispatching or handling managed events from the view, and there isn’t really any reason to use [Init] or [Destroy] on the view either.

So how did we do this? Well, we implemented the tag, which specifies a couple of parameters, namely property and idRef – Property being the property name you want to inject into and idRef being the ID of the object you want to inject.

<Inject
property="someObject"
idRef="bob"/>

This tag replaces the configure event or the <Configure/> tag from Parsley.

The implementation is like this:

package parsley.tags
{
	import flash.events.Event;
	import flash.events.EventDispatcher;

	import mx.core.IMXMLObject;

	import org.spicefactory.parsley.core.context.Context;

	import parsley.event.InjectEvent;

	public class Inject extends EventDispatcher implements IMXMLObject
	{

		public var property : String;
		public var idRef : String;

		private var context : Context;
		private var document : Object;

		public function initialized(document:Object, id:String):void
		{
			if( !property || !idRef ) throw new Error("Cannot inject unless property and idRef is provided");
			this.document = document;
			document.addEventListener( Event.ADDED_TO_STAGE, onAddedToStage);
		}

		private function onAddedToStage( event : Event ) : void
		{
			document.dispatchEvent( new InjectEvent( property, idRef ));
		}
	}
}

This tag dispatches an Inject event on the view object which bubbles up to the viewManager. We created a custom view manager which listens for the Inject event, and once it’s caught, it’s retrieving the object from the context and assigning it to the target of the event.

package parsley
{
	import flash.display.DisplayObject;
	import flash.system.ApplicationDomain;

	import mx.core.UIComponent;

	import org.spicefactory.parsley.core.context.Context;
	import org.spicefactory.parsley.core.factory.impl.GlobalFactoryRegistry;
	import org.spicefactory.parsley.core.view.impl.DefaultViewManager;

	import parsley.event.InjectEvent;

	public class InjectAwareViewManager extends DefaultViewManager
	{

		protected var parent : Context;

		public function InjectAwareViewManager(context:Context, domain:ApplicationDomain)
		{
			super(context, domain);
			this.parent = context;
		}

		override public function addViewRoot(view:DisplayObject) : void
		{
			view.addEventListener( InjectEvent.INJECT_EVENT, onInject );
		}

		protected function onInject( event : InjectEvent ) : void
		{
			var target : UIComponent = event.target as UIComponent;
			var property : String = event.property;
			var idRef : String = event.idRef;
			if( idRef )
			{
				target[property] = parent.getObject( idRef );
			}
			event.stopImmediatePropagation();
		}
	}
}

This is far more performant than the configure tag, and serves the purpose in most view implementations.

To get this to work, you’d need to create a new ViewManagerFactory which returns the custom viewManager, and register this with the GlobalFactoryRegistry.

Simples, as Alexander from Meerkat.com says….

Thanks to Tom Sugden at Adobe for his thoughts on how to do this.

It appears a colleague has been looking at the exact same issue as I was looking at, albeit from another angle.
Have a look at his blog, and see how he’s got on with dpHibernate:

http://martypitt.wordpress.com/2009/05/28/dphibernate-and-spring-transactions/

Hi all, and welcome to my first blog post on wordpress.

I was working on a RIA recently using BlazeDS and Spring with Hibernate3, and sure enough, I came across the issue of the transaction having ended before the entity was fully loaded. Using JPA this is a bit of a problem because it is very difficult to get Hibernate to use Eager fetching on anything but a single collection in your object hierarchy. Sure enough, this turned out to be a requirement, so I started looking for solutions.

For the time being I simply implemented the ‘OpenEntityManagerInView’ filter. What does it do? It simply manages the transaction boundries so that Hibernate entities are available within servlets, JSP pages… And within Blaze’s serializer. (Since Blaze is implemented as a servlet, it makes it all relatively easy.)

So easy enough fix – All that was required was

<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
</filter-class>
</filter>

and an appropriate filter mapping, and problem was solved. This might seem like a basic Spring feature to most of you, however – And this is indeed not why I’m posting all this.

In the process of solving this problem I came across an opensource project called DPHibernate (http://code.google.com/p/dphibernate/), and this project goes some way towards addressing the lazy loading issue with Hibernate and Flex Remote Objects.  In summary, it seems to allow the persistenceBag proxies in the lazy hibernate objects to be serialized in their own rights, and that the library will then manage the loading when flex accesses the lazy objects.

This is excellent news, as this kind of thing was a pain to do in the past. Haven’t managed to test this yet, but when I do, I believe it will deserve another post.

To be continued.