Friday, August 29, 2008

Model Glue, ColdSpring, and a Webservice

Last year I had to work on a website project where I chose to use Model Glue:Unity as the MVC framework. It worked out really well. However, once I was done with the app I ended up having to create a C# client app that could synchronize with my web application. As you might imagine a webservice was needed which would expose parts of my model to the client application.

Now, while using MG:U I ended up coming to really appreciate Cold Spring - this post isn't really going to evangelize that great tool - but instead it will explain how I was able to make use of the ColdSpring work I had used with MG:U from within my webservice.

As a minor introduction I really didn't know anything about ColdSpring when I started that project and I definitely didn't know how MG:U was utilizing ColdSpring - I just knew it worked. However, once I created my webservice I didn't really know how to access all of the objects that ColdSpring was managing for me; all my services and gateways were inaccessible to me unless I could somehow get a reference to the MG:U framework that was instantiated by running the web application.

This coupling between my webservice and MG:U was obviously not ideal. However, I really didn't know how to avoid it nor did I have a ton of time to figure out a better solution. So I ended up with a bit of a kludgy hack in my webservice so that I could get the objects from ColdSpring via MG:U thusly:


<cffunction name="getServiceObject" access="private" returntype="any" output="false">
<cfargument name="beanName" type="string" required="true" />
<cfset var keypos= "" />
<cfset var key = "" />
<cflock type="readonly" scope="Application" timeout="10">

<cftry>
<cfset key = cgi.path_translated />
<cfset keypos = listfindnocase(key, "WebServices", "\") -1 />
<cfset key = listgetAt(key, keypos, "\") />
<cfcatch>
</cfcatch>
</cftry>

<cfif Len(key)>
<cfreturn application["#key#"].framework.getBeanFactory().getBean(arguments.beanName) />
<cfelse>
<cfsavecontent variable="key">
<cfdump var="#structKeyList(application)#" />
</cfsavecontent>
<cfthrow type="WebServiceUnavailable" message="The Website has not been initialized since last reboot." />
</cfif>
</cflock>
</cffunction>


Nasty isn't it? Basically my webserivce sits in a subdirectory of the initial application which is how that nasty kludgy approach worked. However my webservice had the dependency that the website had been loaded at least one time since the last reboot of the server in order for the webservice to work - ugh; talk about bad code smell.

Well it turns out there is a much, much easier and cleaner solution to my problem. All of you ColdSpring guru's are probably still trying to figure out why I approached the problem like I did in the first place - and some of you are probably wondering why I didn't just use the ColdSpring Proxy stuff to create the webservice (I don't really know how nor do I understand it yet). Anyway here is what I ended up doing to fix my problem of accessing ColdSpring from my webservice.

Basically I just plopped a new Application.cfc file in my webservices directory. I set a few application settings and then defined just the onApplicationStart method:


<cffunction name="OnApplicationStart">
<cfset application.coldspring = createObject("component","coldspring.beans.DefaultXMLBeanFactory").init() />
<cfset application.coldspring.loadBeansFromXMLFile("path\to\my\mg:u\config\ColdSpring.xml",true) />
</cffunction>


Now my function in my webservice is simplified to this:


<cffunction name="getServiceObject" access="private" returntype="any" output="false">
<cfargument name="beanName" type="string" required="true" />
<cfset var keypos= "" />
<cflock type="readonly" scope="Application" timeout="10">
<cfreturn application.coldspring.getBean(arguments.beanName) />
</cflock>
</cffunction>


Holy Crap that's a lot cleaner. It's amazing what happens when you read the documentation on using ColdSpring and not just on configuring it.

Moral of the story? RTFM

Tuesday, August 26, 2008

nUnit GUI and Debugging in Visual Studio

This is just a short note to help people debug their unit tests a little easier. To most people this will probably seem pretty obvious but since I don't spend a ton of time in the VS environment I thought it was pretty nifty (and it saved me from having to buy something like TestDriven.Net - which rocks btw).

Basically what I needed was a way to debug my unit tests with the visual studio debugger. This is actually pretty easy to accomplish. Just follow these easy steps:

  1. Set your test project as the default project. To do that just right click on the project name in the Solution Explorer pane and choose "Set as Default"
  2. Set the projects "Start Action" to launch the nUnit Gui. To do that right click on the project in the Solution Explorer, Select the "DEBUG" tab, then click the radio button labeled "Start External Program" - then pick the nUnit Gui Runner as the external program.
Now, you can run your test suite. By clicking the run icon in the Visual Studio toolbar the nUnit Gui Runner will popup but no tests will run automatically - however the Gui Runner will be populated with all the tests in your project. Now you just need to pick the test(s) you want to run and run them. If those tests (or the code they call) have any break points the Visual Studio window will reactivate when the breakpoint is reached and you can step through your code.

I hope this helps others embrace unit tests with .Net and Visual Studio.

Thursday, August 21, 2008

Executor - A Handy Utility

Yesterday I was browsing around when I came across the nifty app launching utility called Executor. Executor is sort of like "Launchy" but has a few differences. First off it doesn't support plugins like Launchy. It also doesn't have as much of a fan base. However, I like it better. It has a bunch of nice features and does everything I want it to do.

There are a bunch of "secret" commands and options in it as well. You might be wondering why I like it better than Launchy? Sadly, that isn't easy to answer. Executor just behaves the way I want. It seems to offer me more default options and is pretty darn customizable. It supports hotkeys (which I pretty much love having) for quick application launching. It is more keyword based than Launchy and overall just seems a bit more powerful in it's base configuration.

I don't really need GCal or Twitter or any other web based social media integration with my app launcher - I just want an easy to use and powerful command line tool and Executor fits the bill nicely.

Thursday, August 07, 2008

OT: Managing the Social Mayhem

SocialThing + Ping.fm looks like a great marriage. Now I can post to all and view from all in one centralized place. Sweetness.

Basically, after setting up a ping.fm account (and associating all my other social accounts with it) I then setup a SocialThing account. Social Thing is a life streaming service. Basically that means they aggregate all the bits and pieces of data that normally flows on all your different services like twitter and facebook and displays them in one neat and easy to read place. However, SocialThing also now has integrated with ping.fm so you can post a note to ping.fm. Ping.fm then propogates that post out to all those same services.

Before the SocialThing+Ping.fm integration occured you were stuck having to go to Ping.fm (or some similar service) and post your message then you had to go to SocialThing (or some similar service) to read all your friends posts/updates. It was clunky. Now, however, it is a one stop shop of social goodness. You can post your status update/microblog message and follow everyone elses activity all from the same place.

Friday, August 01, 2008

SQL SERVER CE - Change a Column Name

Lets say you have a column that is currently storing just integers but you really want it to store nvarchars in SQL Server CE - what do you do?

Well, you can just modify the column definition (it seems, though I could be wrong). Instead you have to alter the table to create the new column, copy the data over from the int column to the nvarchar column, drop the int column, recreate it as a nvarchar column, copy the data back, and then delete the temp column you started with. Something like this:


alter table myTable add tempCol nvarchar(10);
update myTable set tempCol = myIDcol;
alter table myTable drop column myIDcol;
alter table myTable add myIDcol nvarchar(10);
update myTable set myIDcol = tempCol;
alter table drop column tempCol;



Fun isn't it? If there is a better way to do this in SQL Server CE please share! Thanks.