<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>swiftsuspenders &#8211; Software, Fitness, and Gaming &#8211; Jesse Warden</title>
	<atom:link href="https://jessewarden.com/tag/swiftsuspenders/feed" rel="self" type="application/rss+xml" />
	<link>https://jessewarden.com</link>
	<description>Software &#124; Fitness &#124; Gaming</description>
	<lastBuildDate>Mon, 23 May 2011 15:58:48 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://jessewarden.com/wp-content/uploads/2016/08/cropped-Lambda2-32x32.png</url>
	<title>swiftsuspenders &#8211; Software, Fitness, and Gaming &#8211; Jesse Warden</title>
	<link>https://jessewarden.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Adding Dependency Injection to Cairngorm 2.x via SwiftSuspenders (or Robotlegs) for Middle Tier Mocking</title>
		<link>https://jessewarden.com/2011/05/adding-dependency-injection-to-cairngorm-2-x-via-swiftsuspenders-or-robotlegs-for-middle-tier-mocking.html</link>
					<comments>https://jessewarden.com/2011/05/adding-dependency-injection-to-cairngorm-2-x-via-swiftsuspenders-or-robotlegs-for-middle-tier-mocking.html#comments</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Mon, 23 May 2011 13:27:41 +0000</pubDate>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[cairngorm]]></category>
		<category><![CDATA[dependency]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[injection]]></category>
		<category><![CDATA[robotlegs]]></category>
		<category><![CDATA[swiftsuspenders]]></category>
		<guid isPermaLink="false">http://jessewarden.com/?p=2699</guid>

					<description><![CDATA[Introduction The following discusses how to utilize Dependency Injection in the Cairngorm 2.x framework, explains why you&#8217;d want to do this, and shows the code you need. Included is a brief explanation of how you Mock or &#8220;fake&#8221; a backend until it&#8217;s ready so you can build your Flex app without waiting for the web [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><span style="color: #000000;"><strong>Introduction</strong></span></p>
<p>The following discusses how to utilize Dependency Injection in the Cairngorm 2.x framework, explains why you&#8217;d want to do this, and shows the code you need. Included is a brief explanation of how you Mock or &#8220;fake&#8221; a backend until it&#8217;s ready so you can build your Flex app without waiting for the web services to be ready.</p>
<p><span id="more-2699"></span><strong>NOTE</strong>: I do not professionally recommend you do the following integration outlined in this article. Instead, I suggest you utilize <a href="http://robotlegs.org">Robotlegs</a> orÂ <a href="http://www.spicefactory.org/parsley/">Parsley</a> at the start of any Flex application of large size. They, and other frameworks of their ilk (<a href="http://swizframework.org/">Swiz</a>, <a href="http://puremvc.org/">PureMVC</a>, etc), have solved many glaring architecture problems Cairngorm has over the past 7 years. There is a reason <a href="http://opensource.adobe.com/wiki/display/cairngorm/Cairngorm+3">Cairngorm 3</a> is a bunch of good ideas, and not a framework. Adobe recommends you use Cairngorm 3 with one of the aforementioned frameworks.</p>
<p><strong>Context</strong></p>
<p>Your project uses Cairngorm 2.x. Your back-end services aren&#8217;t done yet. Your team has a lot of GUI code to write. Ya&#8217;ll cannot wait for the middle tier to be done to actually move forward. The way to solve this is to use Mocks; classes that fake your middle tier. They&#8217;ll take a few seconds to respond, use the same methods, dispatch the same events, and return real ValueObjects. This allows you to write real GUI and Application logic code without having to wait on your server to work. If you&#8217;re server works, and then it turns out to be premature (i.e. &#8220;That isn&#8217;t supposed to happen&#8230; worked for me&#8230;&#8221;), you can go back to your Mocks until it&#8217;s &#8220;really&#8221; ready.</p>
<p><strong>Mocking a Middle Tier</strong></p>
<p>The easiest way to do this strategy is via coding by contract and Dependency Injection. You code to interfaces instead of concrete implementations (you use ILoginService vs LoginService). Your injection rules then have a switch: &#8220;real&#8221; and &#8220;fake&#8221;. If real is turned on, you hit a real server. If fake is turned on instead, you don&#8217;t hit anything. Both take a few seconds (read, more than 1 frame), and both return real ValueObjects. The fake ones do this by hardcoding the return values to something that would commonly be returned.</p>
<p>Examples include faking a login. The MockLoginService will take a hardcoded username and password and return a hardcoded UserVO. The real LoginService will take any username and password, and return a UserVO if successfully logged in that the server gave it.</p>
<p>Both use the same API. Both dispatch the exact same Event(s). Both expose the same return values. The key is the both implement the same ILoginService interface. This allows your DI framework to create the service for you vs. using Boolean or Conditional Compilation flags everywhere.</p>
<p><strong>Example Login Service</strong></p>
<p>Here&#8217;s an example of a real Login Service, specifically a Cairngorm Business Delegate that is assumed to have a predefined remoting-config.xml that defines your BlazeDS/Java services, and you access via a ServicesLocator/Services Singleton.</p>
<pre lang="actionscript">package com.jxl.services
{
   import mx.rpc.IResponder;
   import mx.rpc.AsyncToken;
   import mx.rpc.Responder;
   import mx.rpc.events.FaultEvent;
   import mx.rpc.events.ResultEvent;
   import mx.rpc.remoting.Operation;
   import mx.rpc.remoting.RemoteObject;

   public class LoginService implements ILoginService
   {

      private var responder:IResponder;
      private var service:RemoteObject;

      public function LoginService(responder:IResponder):void
      {
         this.responder    = responder;
         this.service      = ServiceLocator.instance.getRemoteObject( "LoginService" );
      }

      public function login(username:String, password:String):void
      {
         var operation:Operation    = service.getOperation("login") as Operation;
         var responder:Responder    = new Responder(onResult, onFault);
         var token:AsyncToken       = operation.send(username, password);
         token.addResponder(responder);
      }

      private function onResult(event:ResultEvent):void
      {
         responder.result(event);
      }

      private function onFault(event:FaultEvent):void
      {
         responder.fault(event);
      }
   }
}</pre>
<p>Notice it takes your username and password, passes to the predefined service, and awaits a response from the passed in Responder.</p>
<p>Now here&#8217;s the fake one:</p>
<pre lang="actionscript">package com.jxl.services.mocks
{

   import flash.utils.setTimeout;

   import mx.rpc.IResponder;
   import mx.rpc.Responder;
   import mx.rpc.events.ResultEvent;

   public class MockLoginService implements ILoginService
   {

      private var responder:IResponder;

      public function MockLoginService(responder:IResponder):void
      {
         this.responder = responder;
      }

      public function login(username:String, password:String):void
      {
         setTimeout(onResult, 2 * 1000);
      }

      private function onResult():void
      {
         var fakeUser:UserVO    = new UserVO();
         fakeUser.firstName     = "Jesse";
         fakeUser.lastName      = "Warden";
         responder.result(new ResultEvent(ResultEvent.RESULT, false, true, fakeUser));
      }
   }
}</pre>
<p>It, too, implements the ILoginService, as well as dispatching the ResultEvent to the passed in Responder. Notice it creates a fake user, doesn&#8217;t care what you pass in, and uses a 2 second timer to emulate a server call. This seems trivial, but a lot of people coming to ActionScript for the first time from other blocking languages such as C++ or Java assume the server will respond in the same block/stack of code vs. waiting for an event. Using this timer helps surface such workflow issues early.</p>
<p>And the ILoginService interface both of the above implement:</p>
<pre>package com.jxl.services
{
   public interface ILoginService
   {
      function login(username:String, password:String):void;
   }
}</pre>
<p><strong>Using Boolean Constants</strong></p>
<p>Before Dependency Injection frameworks, you&#8217;d use Boolean config variables in some Constants file:</p>
<pre lang="actionscript">package
{
   public class Constants
   {
      public static const USE_MOCKS:Boolean = true;
   }
}</pre>
<p>And then implemented in your Cairngorm Command like so:</p>
<pre lang="actionscript">package com.jxl.commands
{
   import com.jxl.services.LoginService;
   import com.jxl.services.mocks.MockLoginService;
   import com.jxl.services.ILoginService;
   import com.jxl.models.LoginModel;
   import com.jxl.events.controller.LoginEvent;

   import com.adobe.cairngorm.commands.Command;
   import com.adobe.cairngorm.control.CairngormEvent;

   import mx.rpc.Responder;

   public class LoginCommand implements Command
   {
      private var responder:Responder;
      private var delegate:ILoginService;

      public function execute(event:CairngormEvent):void
      {
         responder                 = new Responder(onLoginSuccess, onLoginError);
         var loginEvent:LoginEvent = event as LoginEvent;

         if(Constants.USE_MOCKS == false)
         {
            delegate               = new LoginService(responder);
         }
         else
         {
            delegate               = new MockLoginService(responder);
         }

         delegate.login(loginEvent.username, loginEvent.password);
      }

      private function onLoginSuccess(event:ResultEvent):void
      {
         LoginModel.instance.loggedInUser = event.result as UserVO;
      }

      private function onLoginError(event:FaultEvent):void
      {
         trace("LoginCommand::onLoginError");
      }
   }
}</pre>
<p>There are 3 problems with the above approach.</p>
<ol>
<li>It&#8217;s all or nothing. Once you set the Constants&#8217; file USE_MOCKS variable to false, EVERYTHING is in production mode. A lot of times a critical service will go out of commission, or be updated. You don&#8217;t have the ability using the above to target specific Services/BusinessDelegates to be mocked, while the rest are still production.</li>
<li>QA will often request certain services fail intentionally while others succeed; using the above prevents you from giving QA that ability.</li>
<li>You have if/then&#8217;s everywhere. This can lead to code bloat, specifically in Commands that actually <a href="http://jessewarden.com/2007/08/10-tips-for-working-with-cairngorm.html">handle multiple events vs. single event types</a> (see Point #6)&#8230; or Commands that handle the service call chaining themselves (similarÂ to <a href="http://knowledge.robotlegs.org/discussions/questions/115-using-the-asynccommand-with-services-callbacks">Robotlegs AsyncCommand&#8217;s</a> that choose not to fork, but instead handle everything internally (+ rollback if needed).</li>
</ol>
<p><strong>Using Conditional Compilation</strong></p>
<p>Same as the above, but uses constants defined by the compiler to determine whether to even compile in certain code. Wherever you configure mxmlc, it&#8217;d look something like this:</p>
<pre lang="actionscript">-define=SERVICES::usemocks,true</pre>
<p>And then in your Cairngorm Command:</p>
<pre lang="actionscript">if(SERVICES::usemocks == false)
   delegate = new LoginService(responder);

if(SERVICES::usemocks == true)
   delegate = new MockLoginService(responder);</pre>
<p>Just as ghetto; you still have C-like #ifdef&#8217;s everywhere. Gross. Manual. Prone to error. Still globally set on or off; all or nothing. Additionally, requires you to configure the compiler vs. &#8220;just code&#8221;. More crud to setup, maintain, and ensure goes into your automated build configuration.</p>
<p><strong>Using Dependency Injection via SwiftSuspenders</strong></p>
<p>NOTE: You don&#8217;tÂ necessarilyÂ have to use <a href="https://github.com/tschneidereit/SwiftSuspenders/">SwiftSuspenders</a>, or even Robotlegs. I&#8217;m just using them in this example because I know them.</p>
<p>Dependency Injection, also know as Inversion of Control, or IoC is a way to have your dependencies injected into your class for you. It&#8217;s the &#8220;new &#8216;new'&#8221;. Instead of you going:</p>
<pre lang="actionscript">delegate = new LoginService(responder);</pre>
<p>This is done for you; you never write new Something again for your dependencies. Now generally, it&#8217;s fine to code to Concrete implementations. But hopefully, you can see how coding by contract (ie using ILoginService) above allows you to configure WHICH Login Service to use; the real one or the fake one.</p>
<p>This is where DI comes in. You configure that stuff in one place; globally, or on a case by case basis, usually using ActionScript. An example, this time using the same Constants variable and an already made SwiftSuspenders injector:</p>
<pre lang="actionscript">if(Constants.USE_MOCKS == false)
{
   injector.mapClass(ILoginService, LoginService);
}
else
{
   injector.mapClass(ILoginService, MockLoginService);
}</pre>
<p>As you can see, this accomplishes a few things.</p>
<p>First, it makes your configuration rules DRY. Instead of having if/then&#8217;s or SERVICES::usemocks everywhere, you do it all in one place/class. Second, you can choose to turn it off for specific services. Third, anywhere you utilize ILoginService, this injection rule will run, allowing you to use the same rules in unit tests (although you shouldn&#8217;t, hehe), and any other place you&#8217;re coding by contract. It also keeps your code concise; it&#8217;s just coding to the interface; it has no clue what real type it actually is (LoginService or MockLoginService).</p>
<p>For our purposes, this is perfect for setting up and configuring mocks. We can configure our entire application to use real services once they come online&#8230; or just 1 at a time, all in one place.</p>
<p><strong>DI in Cairngorm</strong></p>
<p>Cairngorm has aÂ prescribedÂ way of writing yourÂ serviceÂ layer (sort of&#8230; ok not really). Thus it&#8217;s implied you&#8217;ll be using BusinessDelegates to connect to your back end and get your data. Additionally, Cairngorm prescribes you utilize Commands to their interface to instantiate and utilize those Services/BusinessDelegates.</p>
<p>Cairngorm 2.x does not have a documented way of doing Dependency Injection. There is a <a href="http://www.springsource.org/extensions/se-springactionscript-as">SpringAS</a> adapter for CairngormÂ <a href="http://davidbuhler.org/">David Buhler</a> told me about on Facebook, but I haven&#8217;t investigated it myself.</p>
<p>There are 3 challenges you need to be aware of:</p>
<ol>
<li>Cairngorm is typically deployed as a SWC; a library. Thus, you don&#8217;t have access to the source to modify. You could, but this makes people nervous.</li>
<li>Cairngorm creates Commands internally in it&#8217;s FrontController.</li>
<li>BusinessDelegates utilize an IResponder for their constructors (by convention), which would require you to utilize constructor injection. While it&#8217;s supported, it&#8217;s confusing for people who haven&#8217;t done it before. Even so, mx.rpc.Responders in turn have a specific constructor only approach to creation. In short, it&#8217;s &#8220;just easier&#8221; to modify the convention of setting responders on BusinessDelegates after they are created via getter/setters vs. using <a href="https://gist.github.com/418821">Alan Shaw&#8217;s Factory injection rule modification</a>&#8230; and even that doesn&#8217;t work at the instance level where it&#8217;s most often inside of Commands anyway. More on this in a bit.</li>
</ol>
<p>So we can&#8217;t modify Cairngorm&#8217;s source code, we need to inject our dependencies manually into Cairngorm Commands, and we need to slightly modify the Cairngorm BusinessDelegate convention to use a public setter vs. a constructor parameter.</p>
<p>No problem. Here&#8217;s the 3 steps you need to follow.</p>
<p><strong>Step 1: Setup Your Injection Rules</strong></p>
<p>You need to setup your injection rules. Since I&#8217;m comfortable using SwiftSuspenders, and Robotlegs already does most of the hard work inside it&#8217;s Context class, I&#8217;ll just use that; I create a MainContext.as class that sets up my rules and instantiate it in my main Flex Application class.</p>
<p>Here&#8217;s the class (again, you&#8217;re welcome to use your own ActionScript DI library like Swiz/Parsely or any Guice/SpringÂ derivatives):</p>
<pre lang="actionscript">package
{
   import com.jxl.events.controller.AppEvent

   import flash.display.DisplayObjectContainer;

   import org.robotlegs.mvcs.Context;

   [Event(name="applicationReady", type="com.jxl.events.controller.AppEvent")]
   public class MainContext extends Context
   {
      public function MainContext(contextView:DisplayObjectContainer=null, autoStartup:Boolean=true)
      {
         super(contextView, autoStartup);
      }

      public override function startup():void
      {
         if(Constants.USE_MOCKS == false)
         {
            injector.mapClass(ILoginService, LoginService);
         }
         else
         {
            injector.mapClass(ILoginService, MockLoginService);
         }
         var appEvent:AppEvent = new AppEvent(AppEvent.APP_READY);
         appEvent.injector     = injector;
         dispatchEvent(appEvent);
      }
   }
}</pre>
<p><strong>Step 2: Give Cairngorm Injection Powers</strong></p>
<p>Most of the work in a Cairngorm application is done in Commands. This is where we&#8217;ll need to inject the majority of our dependencies.Â In Cairngorm, you extend its FrontController class to basically wire up CairngormEvents that are dispatched to run certain Commands. Internally, it&#8217;ll create &amp; execute these command classes for you. We need to override this behavior so we can inject our dependencies before the Command&#8217;s execute method is called. This implies the class that extends FrontController even has an injector, which it doesn&#8217;t.</p>
<p>So how do we go about it?</p>
<ol>
<li>Give your FrontController.as sub-class an injector public property.</li>
<li>give your FrontController an injector instance</li>
<li>override executeCommand to inject into the Command class</li>
</ol>
<p>You&#8217;ll notice in Step 1 I dispatch an &#8220;AppEvent&#8221; and attach the MainContext&#8217;s injector property. This is because the Cairngorm FrontController needs it, and MainContext makes that a protected property. Putting it on an event class allows us to know when it&#8217;s ready to use, and to smuggle it out of the class so others can use it.</p>
<p>First, make your public property addition to your FrontController sub-class:</p>
<pre lang="actionscript">public var injector:Injector;</pre>
<p>Second, set it. I do this in the Flex 4 Application class, like so:</p>
<pre lang="mxml">&lt;fx:Declarations&gt;
   &lt;jxl:MainContext contextView="{this}" applicationReady="onInjectionsReady(event)" /&gt;
   &lt;cairngorm:MainController /&gt;
&lt;/fx:Declarations&gt;

&lt;fx:Script&gt;&lt;![CDATA[
   private function onAppReady(event:AppReady):void
   {
      mainController.injector = event.injector;
   }
]]&gt;&lt;/fx:Script&gt;</pre>
<p>Third, override executeCommand in your FrontController sub-class. It looks like this:</p>
<pre lang="actionscript">protected function executeCommand( event : CairngormEvent ) : void
{
   var commandToInitialise : Class = getCommand( event.type );
   var commandToExecute : ICommand = new commandToInitialise();

   commandToExecute.execute( event );
}</pre>
<p>Make it look like this:</p>
<pre lang="actionscript">protected override function executeCommand( event : CairngormEvent ) : void
{
   var commandToInitialise : Class = getCommand( event.type );
   var commandToExecute : ICommand = new commandToInitialise();
   injector.injectInto(commandToExecute);
   commandToExecute.execute( event );
}</pre>
<p>&nbsp;</p>
<p><strong>Step 3: Implement Your Commands &amp; BusinessDelegates</strong></p>
<p>First, here&#8217;s our modified LoginCommand. Notice 3 things. First, the delegate is now a public variable that has the [Inject] tag on top; it must be public otherwise the [Inject] tag won&#8217;t work. Second, notice we don&#8217;t instantiate delegate; we just assume (rightly so) it&#8217;s already instantiated. Third, and most important; we&#8217;re setting the responder directly on the Delegate vs. putting it in the constructor like a lot of Cairngorm examples do.</p>
<p>Remember, whether we&#8217;re using Mocks or a real server, the Command will stay the exact same.</p>
<pre lang="actionscript">package com.jxl.commands
{
   import com.jxl.services.LoginService;
   import com.jxl.services.mocks.MockLoginService;
   import com.jxl.services.ILoginService;
   import com.jxl.models.LoginModel;
   import com.jxl.events.controller.LoginEvent;

    import com.adobe.cairngorm.commands.Command;
    import com.adobe.cairngorm.control.CairngormEvent;

    import mx.rpc.Responder;

    public class LoginCommand implements Command
    {
      [Inject]
      public var delegate:ILoginService;

      public function execute(event:CairngormEvent):void
        {
         var loginEvent:LoginEvent = event as LoginEvent;

         delegate.responder = new Responder(onLoginSuccess, onLoginError);
         delegate.login(loginEvent.username, loginEvent.password);
        }

      private function onLoginSuccess(event:ResultEvent):void
      {
         LoginModel.instance.loggedInUser = event.result as UserVO;
      }

      private function onLoginError(event:FaultEvent):void
      {
         trace("LoginCommand::onLoginError");
      }
    }
}</pre>
<p>Second, just modify your BusinessDelegates on how they get IResponders. So, instead of this:</p>
<pre lang="actionscript">private var responder:IResponder;
private var service:RemoteObject;

public function LoginService(responder:IResponder):void
{
   this.responder = responder;
   this.service = ServiceLocator.instance.getRemoteObject( "LoginService" );
}</pre>
<p>&#8230;do this:</p>
<pre lang="actionscript">public var responder:IResponder;
private var service:RemoteObject;

public function LoginService():void
{
   this.service = ServiceLocator.instance.getRemoteObject( "LoginService" );
}</pre>
<p>Now, I&#8217;m one of those people who hates useless getter/setters to that don&#8217;t actually DO anything. That said, you can put getter/setters in interfaces to ensure your BusinessDelegates follow the contract. Up to you; find a convention you like.</p>
<p>&#8230;or just do constructor injection.</p>
<p><strong>Conclusions</strong></p>
<p>I&#8217;ve used Mocks on 3 projects now, 1 small, and 2 large and it has significantly improved my teams velocity in all 3 instances. Usually the person setting up the Mocks tends to be a bottleneck for a day or so, but once in place (and assuming you have some idea of the ValueObjects you need), your team can start moving immediately regardless of the state of your server.</p>
<p>This is helpful in Design Agency work where deadlines are non-negotiable, and the server team is just as stressed as you are. It&#8217;s useful in Enterprise situationsÂ especiallyÂ where you might not have a working server + services + production-like testing environment for 5 Sprints. That&#8217;s at least 3 months with NO dependable services. I&#8217;ve seen it take way longer than that, as well.</p>
<p>Keep in mind too that if there are no injection rules defined, noting will happen. This is important if you&#8217;re converting an existing code base and want to help remove some of the dependencies from it. You can lay your DI framework on top, and Cairngorm wil still work the same. This is nice in that some Cairngorm code bases are some of the largest Flex code bases known to man (IÂ guaranteeÂ you right now someÂ CorvetteÂ drivingÂ ParsleyÂ proponent is claiming his is bigger).</p>
<p>Remember, you just: Setup your injection rules, give the FrontController an injector, and override executeCommand to use that injector to inject into the Command classes for their dependencies. The rest is convention.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2011/05/adding-dependency-injection-to-cairngorm-2-x-via-swiftsuspenders-or-robotlegs-for-middle-tier-mocking.html/feed</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
	</channel>
</rss>
