Blog

horizontal line graphic

Subscribe to Kevin Southworth's Blog  Subscribe to my RSS feed | Categories | Search

Articles from Software Development

Check out my reading list

Thursday, July 19, 2007 @ 4:30 PM :: 212 Views :: 0 Comments ::

Just added a new page to the site that contains my reading list.  Check it out to see books I've read in the past as well as my current queue of books.

Project Downloads have been fixed

Tuesday, June 26, 2007 @ 3:42 PM :: 215 Views :: 0 Comments ::

For those of you that were having issues downloading files from my "projects" page, I have upgraded the module and the downloads should be working correctly again.

Summer Reading List

Friday, June 15, 2007 @ 10:00 PM :: 238 Views :: 0 Comments ::
I'm always trying to keep up with the latest tools and technologies in the software industry (which is a full-time job in itself!) and I thought I'd post this quick list of my current summer reading material.  It's a mix of general software architecture / design and also some specific .NET stuff.

Currently Reading:
Next up (no particular order):
You can also keep tabs on my Amazon Wish List. It's going to be quite a task to finish these before summer ends, I better get cracking!

Where are all the open source .NET projects?

Thursday, April 05, 2007 @ 10:25 PM :: 346 Views :: 3 Comments ::
A colleague and I have been discussing lately the relative lack of open-source software projects that are written in .NET languages (normally C# or VB.NET).  We've been searching for a web-based tool to help us with: task tracking, bug tracking, project management, help desk/support tickets, project scheduling, client/customer interface (where clients can login and check status of their projects).

Searching for these types of open-source projects on Google, Sourceforge, and all the usual places turns up a LOT of PHP, Perl, Python, Java projects, but hardly any .NET projects!  However, just because there are a lot of projects out there in these other languages doesn't mean they are any good (as we're finding out).

My feeling about most open-source projects is that they never really get the "spit and polish" of a commercial application.  Of course there are some outstanding open-source projects that rival many commercial offerings (Apache Webserver, Subversion source control, and the Linux Operating System immediately come to mind) but for the most part the projects you see out there were likely written (or at least started) by one developer who was probably motivated by one of the following:
  • Learning a new programming language
  • Needed a program/application to behave in a very specific way
  • The joy of programming just for the fun of it (yes it can be fun!)
The problem with this is that it seems most open-source projects seems to fall in the realm of that first bullet, where the develope is learning a new language and just needs a project to chew on.  As a result, most of the time these projects are always "in development" or they simply aren't up to par in other areas such as Usability, Reliability, or Feature Set.  Also, most of the time the source code is not something you'd want to touch with a 10ft pole!

However, it's when you combine those last two bullets that you can get some great open-source software like Apache or Linux.  These projects are written by smart and dedicated guys (and gals) who are there for the joy of it.

But back to my original question. Where are all the really cool and blog-worthy open-souce .NET applications?  I know there are some great ones out there (DotNetNuke, NUnit, Commerce Starter Kit, SubSonic) but it pales in comparison to other non-Microsoft languages.

Hmmm...maybe I should shut up and start an open-source .NET project....

SubSonic vs. EntitySpaces – A Battle of OR/Ms

Tuesday, January 30, 2007 @ 11:11 PM :: 4116 Views :: 16 Comments ::

I was quite overwhelmed recently when I started researching  OR/M tools for the latest ASP.NET 2.0 project at work.  There are so many to choose from, all with their own unique take on what it means to be a good object-relational mapping tool.  I only wanted to spend a day or two researching/evaluating OR/M tools, and I narrowed it down to SubSonic and EntitySpaces for my final showdown.

SubSonic

I first heard about SubSonic about 6 months ago from one of the many ASP.NET blogs I subscribe to.  The goal of the project is to bring some of the cool RAD tools from the Ruby-on-Rails world into ASP.NET.  One of the nicest features of SubSonic is that it mostly “just works” without too much effort.  There’s no crazy-complicated XML mapping files (I’m looking at you NHibernate…) or mountains and mountains of auto-generated code to dig through (N-Tiers).  SubSonic utilizes a cool feature of the VS2005 and ASP.NET environment called “Build Providers”. All you have to do is make a few adjustments to your web.config file, add a special file to your App_code directory and you’re done!  Whenever you compile/build your VS solution, SubSonic reads your database schema and dynamically generates Data Access classes.

EntitySpaces

I only recently became familiar with EntitySpaces.  A former co-worker of mine really likes the d00dads architecture, the precursor to EntitySpaces.  EntitySpaces takes the code-generation approach, utilizing the popular free code-generation tool MyGeneration.  EntitySpaces is essentially a few .NET dll’s and some MyGeneration code templates.  You load up MyGeneration, open the Entityspaces templates, point them at your database tables, and MyGeneration will spit out a bunch of Data Access and Biz Logic classes in either C# or VB.NET.  My favorite features of EntitySpaces are it Scaffolding support (to auto-generate administration screens for all of your database tables) and its great support for hierarchical data models.

Shot of a scaffold page (notice the drop-down auto-generated for the FK column)

es2_CropperCapture[1].Jpg

SubSonic

Good Stuff

·         Free and Open Source!

·         Easy to get started / mild learning curve

·         Dynamic Queries

·         Strongly-typed wrapper classes for all your stored procedures

·         Active forums, frequent releases

Chinks in the armor

·         Scaffolding support is buggy

·         Doesn’t handle GUID keys very well

·         Weak support for navigating PK/FK relationships

·         Geared towards ASP.NET only (WinForms is possible)

EntitySpaces

Good Stuff

·         Auto-generated scaffolding is very powerful / time-saving

·         Dynamic Queries

·         Very good support for navigating PK/FK collections in code

·         Able to regenerate Data Access code without affecting your custom business logic

·         Serialization of objects for web services, etc.

·         Active forums / support

Frown Face

·         Not free or open source ($80 for Express edition)

·         No strongly-typed access to stored procedures (it is scheduled for next release though)

Final Thoughts

In the end I chose to drop the $80 for EntitySpaces because of its superior Scaffolding and PK/FK Hierarchical support, both of which have been big time-savers so far, allowing me to focus more on the “real guts” of my application instead of Data Access code.  The addition of stored procedure wrappers in the next version will make it even more attractive in my opinion.   However, I’m definitely going to keep an eye on the SubSonic project, since they are adding features all the time.  The biggest things preventing me from using SubSonic right now are the relatively buggy scaffolding support for GUID data types, as well as the weaker support for navigating hierarchical PK/FK collections in code.

Reasons to Refactor

Wednesday, January 24, 2007 @ 2:05 AM :: 285 Views :: 1 Comments ::
Checklist of reasons to refactor:
  • Code is duplicated
  • A routine is too long
  • A loop is too long or too deeply nested
  • A class has poor cohesion
  • A class interface does not provide a consistent level of abstraction
  • A parameter list has too many parameters
  • Changes within a class tend to be compartmentalized
  • Changes require parallel modifications to multiple classes
  • Inheritance hierarchies have to be modified in parallel
  • Related data items that are used together are not organized into classes
  • A routine uses more features of another class than of its own class
  • A primitive data type is overloaded
  • A class doesn''t do very much
  • A chain of routines passes tramp data
  • A middle man object isn''t doing anything
  • One class is overly intimate with another
  • A routine has a poor name
  • Data members are public
  • A subclass uses only a small percentage of its parents'' routines
  • Comments are used to explain difficult code
  • Global variables are used
  • A routine uses setup code before a routine call or takedown code after a routine call
  • A program contains code that seems like it might be needed someday
Code Complete, Chapter 24

Best Practices for Variables

Wednesday, January 24, 2007 @ 2:04 AM :: 269 Views :: 0 Comments ::
  • Declare and define each variable close to where it''s first used
    • This applies especially to code setup needed right before a loop
  • Localize References to Variables
    • keep subsequent variable references close together (the number of lines between references is called span)
    • minimize the average span
  • Keep "live" time as short as possible
    • "live" time is the number of lines between a variables first reference and its last reference
    • A variable could have short span, but a long live time
    • Goal is to minimize both span and live time
  • Don''t assign a value to a variable until just before the value is used
  • Always start with the most restrictive visibility, and expand only as necessary
    • Favor the smallest possible scope for a variable: local to a loop, local to a routine, private to a class, protected to a class, package to a class
(Code Complete, Chapter 10)

Inheritance or Containment?

Wednesday, January 24, 2007 @ 2:03 AM :: 260 Views :: 0 Comments ::
I''ve been reading Code Complete lately (which is a great book so far), and the author, Steve McConnell, has some good general advice about when to use Inheritance and when to use Containment when designing your classes:
  • If multiple classes share common data but not behavior, create a common object that those classes can contain
  • If multiple classes share common behavior but not data, derive them from a common base class that defines the common routines
  • If multiple classes share common data and behavior, inherit from a common base class that defines the common data and routines
  • Inherit when you want the base class to control your interface; contain when you want to control your interface

Superstition or Understanding?

Wednesday, January 24, 2007 @ 2:03 AM :: 259 Views :: 0 Comments ::
Reading some more of Code Complete tonight, ran across a nice little blurb about a difference between hobbyists and professional programmers.  If you write code which you "feel" is right, but the compiler or the hardware just isn''t doing it correctly, you''re in the realm of superstition.  If you actually understand every line of your code and what it does, you have an understanding.  95% of the time it''s the programmers code that is wrong, not the hardware or the compiler.

Nothing is ever right just because it seems to work.  If you don''t know why it works, it probably doesn't - you just don''t know it yet!

GUI Architecture

Wednesday, January 24, 2007 @ 2:02 AM :: 335 Views :: 0 Comments ::
Ryan sent me a great link to an article by Martin Fowler on "GUI Architecture".  Martin Fowler is almost THE source for knowledge on application design and methodologies.  This post covers a history of approaches to designing GUI systems, capping it off with Model-View-Presenter.

http://www.martinfowler.com/eaaDev/uiArchs.html

Note to self: read up on Model-View-Presenter (MVP) !

Send a file from Excel to ASP.NET web service using VBA macro

Wednesday, January 24, 2007 @ 1:52 AM :: 1403 Views :: 2 Comments ::

The other I had the challenge of figuring out how to add a toolbar button to a MS Excel file that would send the current file to an ASP.NET web service.  The web service could then take some action on the file, such as send it as an email attachment, or log it to a database.

You''ll need the following tools/downloads (in addition to MS Excel and Visual Studio 2003/2005)

Microsoft Office 2003 Web Services Toolkit

  1. Create the ASP.NET Web Service to receive the file. I used VS 2005 to create my webservice, but VS 2003 should work fine also.  The key is to have the web method receive a byte[] array as a parameter, since that is what we will be passing from our client-side VBA code.
            [WebMethod]
    public void ReceiveExcelFileBytes(byte[] data)
    {
    Console.Write(data);
    Stream output = new FileStream(
    @"C:\WINDOWS\TEMP\data.xls",FileMode.Create);
    BinaryWriter outputWriter = new BinaryWriter(output);
    outputWriter.Write(data);
    outputWriter.Close();
    output.Close();
    }
  2. The next step is to write our VBA code inside MS Excel. Create a new Excel file and open it. Open the Visual Basic Editor by pressing Alt-F11. Add a new "Module" and type in the code below:
    Dim sMenu As String

    Sub AddCustomButton()

    Dim oCB As CommandBar
    Dim oCtl As CommandBarControl
    Dim newMenu As Object ''CommandBarControl
    Dim ctrlButton As Object ''CommandBarControl

    sMenu = "Send to Webservice"

    On Error Resume Next
    Application.CommandBars("Formatting").Controls(sMenu).Delete
    On Error GoTo 0

    Set oCB = Application.CommandBars("Formatting")
    Set oCtl = oCB.Controls.Add(
    Type:=msoControlButton, temporary:=True)

    With oCtl
    .BeginGroup = True
    .Caption = sMenu
    .FaceId = 197
    .Style = msoButtonIconAndCaption
    .OnAction = "SaveToWebservice"
    End With

    End Sub
  3. Next we need to hook-up our function to the Workbook_Open event. Double-click on "ThisWorkbook" in the VBA Editor and type in the following for the Workbook_Open event handler:
    Private Sub Workbook_Open()
    AddCustomButton
    End Sub
  4. Make sure have installed the Office 2003 Web Service Toolkit, we''ll be using it to generate a VBA proxy for our ASP.NET webservice. Inside the VBA editor, go to "Tools -> Web Service References" menu and add a reference to the URL of your ASP.NET webservice that was created in step # 1 above. This will generate some VBA code that we can use to call our ASP.NET webservice from VBA.

  5. Now we need to connect our custom toolbar button to some code that actually sends the file across the wire. Jump back to the VBA module (where we have our AddCustomButton() method, and add the following code:
    Sub SaveToWebservice()

    On Error GoTo Error_Handler

    Dim backupFile As String
    Dim fhandle As Long
    Dim webservice As New clsws_ExcelWebService

    backupFile = "C:\WINDOWS\TEMP\file_backup.xls"

    '' Save a backup copy to retain our VBA code
    ActiveWorkbook.SaveCopyAs backupFile

    Dim TypeBinary
    Dim oStream As ADODB.Stream

    '' Create the object
    Set oStream = CreateObject("ADODB.Stream")

    '' Open our file
    oStream.Open
    oStream.Type = adTypeBinary
    oStream.LoadFromFile backupFile

    '' Retreive binary data from the file
    Dim dataLong As Long
    Dim dataBytes As Variant
    Dim dataString As String

    dataBytes = oStream.Read

    '' call the webservice
    webservice.wsm_ReceiveExcelFileBytes (dataBytes)

    oStream.Close

    MsgBox ("Successfully sent")

    Exit Sub

    Error_Handler:
    MsgBox Err.Description &
    " (" & Err.Number & ")",
    vbOKOnly + vbCritical
    Exit Sub

    End Sub

 

Smart Clients in .NET 2.0

Wednesday, January 24, 2007 @ 1:51 AM :: 195 Views :: 0 Comments ::

I found a really good article on CodeProject this weekend on Smart Client development. It goes into a lot of detail on how to implement a Smart Client type application, but it also has some good stuff relating to Design Patterns, and how to implement an “Automation” module similar to MS Word. I haven’t finished the whole article yet, but it looks really informative. Plus you can download all the source code for his sample app :)

http://www.codeproject.com/smartclient/SmartClientSOA.asp

Javascript Event Handlers

Wednesday, January 24, 2007 @ 1:51 AM :: 232 Views :: 0 Comments ::

I was looking for a way to attach an event to ALL the input fields on a web page and found this little ditty that lets you attach event handlers to all instances of an element with one call :)

<html>

<head>

<title>title>

<script type="text/javascript" language="Javascript">

function addEvent(obj, evType, fn)

{

    if (obj.addEventListener)

    {

        obj.addEventListener(evType, fn, true);

        return true;

    }

    else if (obj.attachEvent)

    {

        var r = obj.attachEvent("on"+evType, fn);

        return r;

    }

    else

    {

        return false;

    }

}

 

addEvent(window, ''load'', function() {

 var input;

 var inputs = document.getElementsByTagName(''input'');

 for (var i = 0; (input = inputs[i]); i++) {

   addEvent(input, ''blur'', myBlur);

 }

}

);

 

function myBlur()

{

    alert("My Blur");

}

 

script>

head>

<body>

<form name="myform">

header

name: <input type="text" name="fname" /><br>

email: <input type="text" name="femail" /><br>

footer

form>

body>

html>

When the window loads, this code will select all the "input" elements on the page and attach my custom function/event handler "myBlur" to each of them.  Which means that anytime ANY of the input fields loses focus, the myBlur function will be called

SQL Server 2005 "COALESCE()" Function

Wednesday, January 24, 2007 @ 1:47 AM :: 1463 Views :: 0 Comments ::

The COALESCE() function in SQL Server 2005 is cool.  Say you have a database schema as follows (primary keys highlighted in bold):

Widget
widgetId
widgetName

Category
categoryId
categoryName

WidgetCategories
widgetId
categoryId

According to the schema, one Widget could be in zero or more categories. Of course we can write queries to return rows of widgets, and we can write queries to return WidgetCategories for a specific Widget. But what if we wanted to select 1 specific widget by widgetId, and in that row have a column called "categories" that held a comma-separated list of categories that the widget is in?  This might be useful for some kind of summary page where you would want to see all the categories a widget is in, in ONE QUERY.

Enter the COALESCE() function!  Check out the SQL Function below and the SELECT query after it:

    2 CREATE FUNCTION dbo.fWidgetCategories

    3 (@widgetId int)

    4 RETURNS varchar(5000) AS

    5 BEGIN

    6  DECLARE @list varchar(5000)

    7         SELECT @list = COALESCE(@list + '', '','''') + Category.[categoryName]

    8         FROM Category C INNER JOIN WidgetCategory WC

    9         ON WC.widgetId = C.widgetId

   10         WHERE WC.widgetId = @widgetId

   11       RETURN @list

   12 END

The SELECT query:

    2 SELECT W.widgetName, dbo.fWidgetCategories(W.widgetId) AS categories

    3 FROM Widget W

These two things will accomplish exactly what we are looking for and return:

widgetName                    categories
widgetA                           sprockets, rockets
widgetB                            gizmos, gadgets

Very cool!  I believe the COALESCE function is present in SQL Server 2000 also.

on-site hacking

Wednesday, January 24, 2007 @ 1:46 AM :: 206 Views :: 0 Comments ::

Something caught my attention on the show "Excavators" on the Discovery Channel tonight.  I don''t watch this show regularly, but sometimes I just leave the Discovery Channel on in the background at home and then pay attention when something interesting comes on.

Anyway, the show is about these HUGE excavating machines that are used in massive open-air mining operations to shovel earth into really big trucks that haul it away and process it.  I don''t know all the exact specs of the machine because I just caught the last third of the show, but if you stood next to one of its caterpillar tracks your head would only be about halfway to the top of the track!

In addition to all of the mechanical complexities of the shovel, it also had an extensive amount of electrical sensors and circuitry (I think they said something like 1 million feet of electrical wire!) all controlled by a central computer.  The operator of the rig has a monitor with a custom GUI on it that is used to control the digging operations and the movement of the rig in general.

Now, the show was mainly about the assembly of this thing at the dig site (since they''re too big to transport in one piece) and how they had these teams of mechanical engineers and electricians assembling this thing on-site over a period of about 8 months.  The show really focused on the problems that arose in the last 7 days before the "launch date" (the date in which it was scheduled to start digging).  Once the electricians had run all the wires and connected everything, it was time to do some test runs with the digger and the caterpillars, and this is where it caught my attention.

Since the entire excavator is controlled by a central computer (called the "Centurion" system) it makes sense that they would have the software guys on-hand.  The crew ran into a couple very major problems:

  • A software bug was preventing the main drum (the part that raises and lowers the digging arm) from turning/moving at all
  • A software "typo" (as described by the software engineer working on-site) was preventing the excavator from moving its caterpillar tracks (preventing any movement at all of the rig)

What was astonishing to me was the WAY in which these guys went about debugging:

  1. Plug in a laptop to the excavator''s computer system
  2. Open up some kind of IDE (couldn''t tell what it was or the language from the TV screen)
  3. EDIT THE CODE DIRECTLY ON THE EXCAVATOR
  4. Compile
  5. Test if the code change fixed the specific problem (it did)
  6. Fix other problems that arose as a result of the first code fix (there were several, including one that could cause one of the motors to catch on fire!!)
  7. Call it good and continue

Now, these guys were in a time crunch with a $10 million piece of equipment and they had to get it done, but I have to say: Where''s the rigorous QA process?

At my place of work, we try to avoid the scenario of making code changes on a live/production system because you never know the full ramifications of any change you make.  Even after extensive testing in a staging environment, critical bugs can still arise.

It was just kind of a shock to me that:

  1. These guys had such serious/critical bugs that they didn''t know about (they gave me the impression that they had just written the code that morning!)
  2. They (and their customer) were totally comfortable with making changes right on the live system

This kind of thing makes me think a lot harder about industries where software plays a much more critical role, such as medical monitoring systems and equipment...  "Sorry about the defibrillator that fried your heart, turns out we put that damn decimal place one spot too far to the right...."