Saturday, October 27, 2007

Elegance Awaits

It's not been long since I jumped ship from my company blog and started posting here again.

Never being one to stand still I'm moving again this time to Elegant Code.

I'd like to extend a big thank you to David Starr for allowing myself, David Betts and Jarod Ferguson to capitalize on the excellent brand that he has built. This is going to be so much fun...

Friday, October 26, 2007

SQL Anywhere Tool Issues

Lately I've been working with SQL Anywhere 10. It's always hard working with new because invariably different paradigms are used (which is good) and of course it takes time to grok them. However knowing this doesn't stop me from being frustrated during the learning.

And unfortunately sometimes parts of the toolset are below par. Interactive SQL is an example of a truly horrible tool. It lacks any advanced features. F5 executes (good) but to execute a selected portion of the SQL you have to hit F9 which gets me every time.

I just exited the tool and it prompted me to save the changes that I had made to a SQL script. All looked good and I said yes. Then I was informed that the file was locked and the app just closed. A stream of expletives was issued from my mouth. Just what I need on a Fri afternoon.

CruiseControl.NET and MSBuild

I've used NAnt for years. But for many reasons on a new project I decided to give MSBuild a shot. Everything worked great on my laptop but when I moved to the CC.NET build server I ran into a few problems. I thought that it would be useful to document the problems and solutions:

Issue 1

<error code="MSB4019" file="C:\CruiseControlData\abf\WorkingDirectory\Website\ABF.csproj"

      line="544" column="11">

  <![CDATA[The imported project "C:\Program Files\MSBuild\Microsoft\VisualStudio\v8.0\WebApplications\

    Microsoft.WebApplication.targets" was not found. Confirm that the path in the <Import> declaration

    is correct, and that the file exists on disk.]]>

</error>






Thanks to Scott Allan for the answer.



Issue 2



<error code="MSB3091" file="C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets"

      line="1669" column="9">

  <![CDATA[Task failed because "LC.exe" was not found, or the .NET Framework SDK v2.0 is not installed.

    The task is looking for "LC.exe" in the "bin" subdirectory beneath the location specified in the

    SDKInstallRootv2.0 value of the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework.

    You may be able to solve the problem by doing one of the following:

      1.) Install the .NET Framework SDK v2.0.

      2.) Manually set the above registry key to the correct location.

      3.) Pass the correct location into the "ToolPath" parameter of the task.]]>

</error>




This one is a little easier because it tells you what to do. I saw some warnings elsewhere in the build output about the SDK being missing so to avoid future issues I downloaded and installed it.



Now everything works. Sweet!

Wednesday, October 24, 2007

NHibernate AliasToBean Transformations

NHibernate's AliasToBean result transformer looks very useful. It allows you to map to unmanaged entities (don't ask why we have some of these!)

If you look at the docs you can see how this is supposed to work. However when I tried to implement this I kept receiving a "NHibernate.QueryException: Return types of SQL query were not specified". To workaround this I had to use the AddScalar() method to define the return types which is actually what I was trying to avoid by using the transformer:

ISQLQuery q =_session.CreateSQLQuery("SELECT c1 ID FROM t1 i WHERE c2 = :value1");
q.SetInt64("value1", value1);
q.SetResultTransformer(Transformers.AliasToBean(typeof(UnmanagedEntity)));
q.AddScalar("ID", NHibernateUtil.String);
return (List< UnmanagedEntity >)q.List< UnmanagedEntity >();

I'll post this on the forums to determine whether my problem is due to a bug or a misunderstanding on my part.

Monday, October 22, 2007

Anonymous Delegate Overuse Anti-Pattern

I like anonymous delegates and generics and use them both a lot. The combination affords considerable flexibility and allows me to keep my code DRY. However it's easy to take any technique too far. Just because you can do something doesn't mean that you should.

For example consider these two methods:
      private const string TEST_DATA = "1,2,3,4";

private string ToXml()
{
StringBuilder sb = new StringBuilder();
foreach (string s in TEST_DATA.Split(','))
{
sb.Append("" + s + "");
}
return sb.ToString();
}

private List ToList()
{
List list = new List();
foreach (string s in TEST_DATA.Split(','))
{
list.Add(s);
}
return list;
}
There is duplication in the two foreach blocks. It is possible to remove this using a combination of anonymous delegates and generics:
      private delegate void MyDelegate(T instance, string s);

private void Process(MyDelegate myDelegate, T instance)
{
foreach (string s in TEST_DATA.Split(','))
{
myDelegate(instance, s);
}
}

private string ToXmlUsingAnonymousDelegate()
{
StringBuilder sb = new StringBuilder();
Process(
delegate(StringBuilder tmp, string s)
{
tmp.Append("" + s + "");
}, sb);
return sb.ToString();
}

private List ToListUsingAnonymousDelegate()
{
List list = new List();
Process(
delegate(List tmp, string s)
{
tmp.Add(s);
}, list);
return list;
}
The resulting code is DRYer but it's definitely not easier to understand. If you had to maintain this how happy would you be?

Monday, October 15, 2007

Unique Error Nightmare

I am working on a web application that uses SQL Anywhere 10. I am in the process of porting the DAL to NHibernate. I wrote a custom driver as the existing one only supports v9 -I'll contribute it once I'm sure that it's working OK.

Everything was going great until Fri afternoon. Some of the code that I haven't ported yet invokes ExecuteScalar() on the IDbCommand.

Suddenly the web app stopped working and I saw this in the Event Log:

Event Type: Error
Event Source: .NET Runtime
Event Category: None
Event ID: 1023
Date: 10/15/2007
Time: 10:59:48 AM
User: N/A
Computer: xxx
Description: .NET Runtime version 2.0.50727.1378 - Fatal Execution Engine Error (7A09239C) (80131506)

I resorted to the debugger (this is hard for a TDD advocate!) and when I used the Immediate Window to inspect the results of the call (Intellisense was not invoking) I saw:

"Cannot obtain value of local or argument "xxx" as it is not available at this instruction pointer, possibly because it has been optimized away."

I wrote a Console app and I see yet another error:

FatalExecutionEngineError was detected
Message: The runtime has encountered a fatal error. The address of the error was at 0x79f63d6d, on thread 0x1554. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.

The wonderful thing is that the problem is not reproducible on any other machine other than my laptop. Don't you just love being a developer!

Friday, October 12, 2007

With Appologies to Roy Osherove (and Oasis)

One of the ideas floated by Roy last weekend in Austin was to compose an ALT.NET song. I was unable to contribute because I had to get to the airport. However last night I was noodling around and this popped out (fnarr!).

It's a shameless rip off of Wonderwall by Oasis. I pretty much kept the second verse intact because it seemed to fit the mood of ALT.NET well. It's a work in progress but given my lack of free time it's not going to be finished anytime soon. So here it is. Enjoy.

Verse 1
Today is gonna be the day
That we're gonna have ourselves a coup
Web Forms and drag and drop are
Shit that we refuse to do
I would really like to try and practice BDD
But I don't know how

Verse 2
Backbeat the word is on the street
That the fire in your heart is out
I'm sure you've heard it all before
But you never really had a doubt
I don't believe that any Mort feels
The way I do about TDD

Bridge
And all the roads we have to walk are winding
The pros and cons of late and early binding
I would really like to try and Practice BDD
But I don't know how

Chorus
Said maybe
I found the thing that's gonna save me
But I wonder if
I am alternative?

Labels:

Monday, October 08, 2007

ALT.NET Aftermath

Wow!

Let me say that again.

Wow!

I really can't think of a superlative that adequately describes the ALT.NET experience. It was certainly everything that I hoped that every other conference that I attended would be (but invariably wasn't). The people were amazing. The level of debate was exceptional. On a given topic almost everyone present was at least conversant. In any session or side-discussion a large portion of the participants had considerable experience with the tool or technique in question. And often there was one or more industry recognized expert present.

What I found particularly interesting was that broadly we all have the same pain points. That is why we could have the endless BDD or anemic domain model discussions. And that is what excites me so much about the future - there are so many problems to solve. And of course it's going to take more than just the ALT.NET community to solve them.

I'm still processing the actual discussions. However the one thing that I am in no doubt about is that the upcoming MVC Framework from Microsoft totally rocks. It's completely extensible and plugable.

Wanna dump Web Forms (the default view) and use Brail. Go ahead.

Wanna use Windsor or Spring.NET or Structure Map for DI. You can.

Note that we're talking about integration with OSS products here. This is a significant and welcome change from the beast of Redmond.

It was already obvious that Scott Guthrie was brilliant but until I saw him in action I did not realize how much I had underestimated him. He's funny too - describing the day that Web Site Projects were released as "the worst day of his life". I can't wait for the CTP (6-8 weeks).

More on ALT.NET later....

Labels: