Categories
Contact Doug!
Learn About Doug!
View Doug Boude's online resume
updated 11/18/2009

View Doug Boude's profile on LinkedIn
Link to me!

Follow Doug Boude on Twitter
Follow me!

Be Doug's friend on Facebook
Befriend me!
(I promise not to follow you home)
OO Lexicon
Chat with Doug!
Recent Entries
You may also be interested in...
Web Hosting

<< May, 2013 >>
SMTWTFS
1234
567891011
12131415161718
19202122232425
262728293031
Search Blog

Recent Comments
Re: Disappearing IE Popup Window During Save/Open Dialog (by LZ at 4/20 7:58 AM)
Re: Create Dynamic WHERE Clauses in PHP (by pooja at 3/20 7:29 AM)
Re: Just What IS a 'Service Layer', Anyway? (by EugenK at 3/07 7:56 PM)
Re: Using Google as your CF Mail Server (by 5starwebteam.com at 2/25 1:27 AM)
Re: Why Provide for Service layer objects in CFWheels? (by Steven Benjamin at 1/25 11:43 AM)
Re: What is an 'Advanced' Coldfusion Developer? (by ColdFusion Developer at 12/24 5:14 AM)
Re: Equivalent of SQL "TOP X" in Oracle (by Ashenafi Desalegn at 12/06 5:29 AM)
Re: PHP Export to Excel Snippet (by serene at 12/05 1:44 AM)
Re: Just What Is 'Application Logic', Anyway? (by Arif at 11/13 8:06 AM)
Re: Hosts File Changes Not Acknowledged on Vista 64 (by Aaron at 10/22 2:31 PM)
Re: PHP Export to Excel Snippet (by Jafar Shah at 10/10 4:28 AM)
Re: Viewing Option Text (in IE7) that's Wider than the Select List (by Chenelle S at 10/04 12:53 PM)
Re: PHP Export to Excel Snippet (by Kilo at 9/26 5:20 PM)
Re: Porting Coldfusion Code to Mura (by tariq at 9/03 9:51 AM)
Re: Just What IS a 'Service Layer', Anyway? (by James at 8/27 4:06 PM)
Re: Calculating Business Hours (by helen at 8/14 2:54 AM)
Re: What IS 'Business Logic', Anyway? (by dougboude at 8/06 11:30 AM)
Re: What IS 'Business Logic', Anyway? (by Adrianne at 8/06 10:29 AM)
Re: Family Law: The Weapon of Choice for Woman Scorned (by dougboude at 8/04 4:39 PM)
Re: Family Law: The Weapon of Choice for Woman Scorned (by Lola LB at 8/04 7:43 AM)
Archives
Photo Albums
Funnies (5)
Family (3)
RSS

Powered by
BlogCFM v1.11

18 April 2012
Providing for Service Layer Objects in CFWheels: Hello Wirebox!
Post 3 of 3

This is the third and final post in a series on making the case for service layer objects (in CFWheels or any framework for that matter!), and two means of implementing them. The second post demonstrated one approach to manually implementing SLOs. This post will demonstrate my MUCH preferred approach: utilizing Ortus Solutions' Wirebox DI/IOC framework.

DI/IOC REVIEW

By way of quick review, the purpose of a Dependency Injection/Inversion Of Control framework is to give the developer ONE PLACE in his app where he can manage the objects that are players within his or her app. For instance, you may have a dataImport object which itself, internally, must be able to communicate with the persistence layer (session, typically), create and manipulate users via a CFWheels User model object, and perhaps access some global utilities via a Utilities object. The manual approach requires you to create and pass in these objects at the time you create your dataImport object. Using Wirebox, you simply ask for the dataImport object, and because you have already pre-defined what it's requirements are, Wirebox worries about building it for you. The advantage? When the app's architecture evolves, and/or object interfaces change, the developer can make those changes in a single spot: the wirebox configuration cfc.

Assuming that at this point you understand why DI/IOC is important, and assuming that you understand the common need to utilize objects in your CFWheels controllers that are NOT directly associated with a database table, allow me to dive in to how I added SLO functionality to CFWheels using Wirebox and the Wirebox Plugin.

Steps I took/Modifications I Made

1. Created a Services folder off the root;
2. Dropped the Wirebox framework off the root;
3. Dropped the Wirebox Plugin zip file into my Plugins directory;
4. Modified the config/wirebox_config cfc so that it knew how my service layer objects should be prepared

That's it! Let's peek at these items in more detail. Well, at least, the ones that aren't already self-explanatory. Oh, I guess that would only be the last step!

In step 4, I needed to tell Wirebox about my service layer objects, the values they require when being created, and the relationships between them. Wirebox provides two basic ways to do this: By annotating your CFCs using the Wirebox Domain Specific Language, or using dependency method chaining. Let me show you a quick example of doing the same thing using each approach.

Let's say you have an object that you want to be given your app's datasource name when it is created. You would manually pass in this value in the object's init method via an argument, so let's go that route. Using Wirebox annotation, you would do this:

 

<cffunction name="init">
 <cfargument name="dsn" type="string" required="true" inject="wheels:setting:datasourcename" />
 <cfset setDSN(arguments.dsn) />
 ....

 
Of note there is the "inject" attribute; Wirebox inspects your CFC before instantiating it and knows that when it does, it should retrieve and pass in the wheels datasourcename during init.

 

Here is what it looks like, in your wirebox_config CFC, using the dependency method chain:

 

<cfset mapPath("services.dataImport").initArg(name="dsn",dsl="wheels:setting:datasourcename");

 

Personally, I prefer (and recommend) the latter method. It keeps your CFCs "normal" (no custom attributes), and the dependency method chain is much easier to read and interpret, all in one line.

Once you have completed step 4, you can write controller methods such as this:

 

<cffunction name="importUsers">
  <!--- perform the data import routine for incoming data... --->
  <cfset result = service("importService").importData(params.dataIn) />
 
  <cfset flashInsert(msg=result) />
  <cfset redirectTo(action="index") />
 </cffunction>

 
Notice the "service()" method; this is what you will use when you want to retrieve a SLO as opposed to a Wheels Model object.

 


DEPENDENCY METHOD CHAIN DETAILS

What good would it be to be able to use SLOs in CFWheels, but those SLOs not be able to use Wheels Model objects internally?? Not much at all. Using the Wirebox plugin, you have the option of enabling your SLOs to have access to Wheels Models. Let's examine a fairly complex Dependency Method Chain definition for the importData SLO.

  

//define our import service layer object
   mapPath("services.importService")
    .asSingleton()
    .initArg(
     name="dsn",
     ref="dsn")
    .initArg(
     name="messageprefix",
     dsl="wheels:setting:messageprefix"
    )
    .property(name="sessionService",ref="sessionStorage")
    .mixins(wheelsORM);//give this object the ability to access Wheels models

 

The first method, 'mapPath', tells wirebox to create an object called 'importService', the CFC for which is found in the services folder.

Next we chain on 'asSingleton()' so that Wirebox knows there should only ever exist one instance of this object.

'initArg' we saw already; we are telling Wirebox that this CFC's init method requires an argument named "dsn", and we want to pass the value contained in the reference ('ref') named "dsn". More on this in a moment.

A second initArg method is chained onto that. Can you imagine what the CFC's init arguments look like? I bet you can. For this initArg(), Wirebox is being told to utilize the Wheels-specific Domain Specific Language (part of this plugin) to retrieve the setting for "messageprefix" (probably being set in config/settings.cfm) and pass that in.

'property()' is telling Wirebox that we want to inject into the object's variables scope, after it has been initialized, a variable named sessionService that is an instance of the sessionStorage object. Again, more on the 'ref' key in a moment.

Lastly, we are telling Wirebox via the 'mixins()' method that we wish for this object to have the ability to call Wheels' 'model()' method internally.Okay, the 'ref'. Also in our configuration cfc we created a value named "dsn" that we can then REFerence in other object definitions. It looks like this:

 

map("dsn").toDSL("wheels:setting:datasourcename");

 

By doing that, any other object that needs the datasourcename value passed in, we can simply say ref="dsn". Same with the sessionStorage service. Elsewhere in our configuration cfc we defined it as

 

map("sessionStorage").to("services.persistenceCFC").asSingleton();

 

If we want to inject that object, now we only need refer to it by 'ref'.

Hopefully that quick overview, and the link to the working data import sample app that uses Wirebox will get you started. The plugin has not yet been approved for inclusion on the CFWheels site, but if you want to play with it now there's a link to it as well. The plugin and the app both contain a READMEDUDE.txt file that you should check out before you do anything else.

Thanks for tuning in!

--------------------------------------

Video demo on youtube

Thorough Wirebox Documentation

Sample App Zip File (be sure to read the READMEDUDE.txt in the zip; you'll have to create one table and edit the datasource setting to get the app to work for you)

Wirebox Plugin (again, be sure to visit it's READMEDUDE.txt)




Posted by dougboude at 11:50 AM | PRINT THIS POST! |Link | 6 comments
Subscription Options

You are not logged in, so your subscription status for this entry is unknown. You can login or register here.

Re: Providing for Service Layer Objects in CFWheels: Hello Wirebox!
Another great value add, Doug. Thanks! And the youtube video was great value as well. Question for you though... when you map to the wheels variables (dsl="wheels:setting:emailserver"), where are such things documented? If I needed some other variable, how would I figure that out?
Posted by geirman on April 20, 2012 at 10:27 AM

Re: Providing for Service Layer Objects in CFWheels: Hello Wirebox!
Hi Chris!
I didn't document all of the possibilities using the "wheels:setting:[some setting]" DSL because...any setting that you can normally access using Wheels' "get()" method, you can use in place of the [some setting] placeholder! I couldn't think of anything else besides settings that you might want or need to pass into a SLO from Wheels, but if you know of anything else (maybe plugins or something?) I can modify the Wheels DSL to accommodate it.
Make sense?
Posted by dougboude on April 20, 2012 at 11:32 AM

Re: Providing for Service Layer Objects in CFWheels: Hello Wirebox!
excellent, it was the "get()" clue that I needed. Thanks... makes perfect sense.
Posted by geirman on April 21, 2012 at 10:24 AM

Re: Providing for Service Layer Objects in CFWheels: Hello Wirebox!
Nice! Thanks for this write up, I'll definitely give this a go.
Posted by Brad on May 3, 2012 at 11:37 AM

Re: Providing for Service Layer Objects in CFWheels: Hello Wirebox!
Doug, just wondered if you tried the FW/1 framework as it is more oriented to what you're blogging about. I haven't used it but curious what you thought of using it vs wheels.
Posted by Ziggy on July 29, 2012 at 4:01 PM

Re: Providing for Service Layer Objects in CFWheels: Hello Wirebox!
Hi Ziggy. I have toyed with FW/1 a little, just enough to get familiar with it. I like it! As far as comparing it to Wheels, I'd say they're both great, depending on the individual developer's tastes. Kind of a "blond versus brunette" situation. ;)
Posted by dougboude on July 30, 2012 at 9:31 AM

Name:   Required
Email:   Required your email address will not be publicly displayed.

Want to receive notifications when new comments are added? Login/Register for an account.

Time to take the Turing Test!!!

Nine plus Eleven equals
Type in the answer to the question you see above:

Your comment:

Sorry, no HTML allowed!