Sunday, September 30, 2012

Is If Condition

Awhile back I wrote about some general rules I had for writing if conditions. So I found it amusing the other day to read a blog post on Coding Horror about new programming jargon and see the following:

Yoda Conditions

Yoda-conditions

Using if(constant == variable) instead of if(variable == constant), like if(4 == foo). Because it's like saying "if blue is the sky" or "if tall is the man".
I will have to add that to my guidelines.

Thursday, August 16, 2012

Return of the Extension Method

Recently a small team of us branched the code to start work on a new feature for a future release while work continued in the mainline for the current upcoming release. As I was working on our new feature I realized that I wanted to extend some common core classes with new functionality. The classes have their own hierarchy tree and normally I would have created a base method for the shared functionality and overridden it for some of the subclasses. However, since I knew that other developers were working on these same classes I looked for ways that I could minimize merging code later. I've written before about extension methods (here and here) and thought this might be a good time to use them.

I quickly ran into an issue where extension methods only work with the same class that the object is cast to. Say for example you have a Shape superclass and Circle subclass. Normally we would pass around Circle objects as Shapes and rely on virtual or abstract methods to provide a common interface. With extension methods there is no inheritance so you have to either explicitly cast our objects or do some type of switching in a common method.

I've created a simple program in LINQPad to demonstrate this behavior:

void Main() {
    // Create a new Circle but cast it as a Shape
    Shape obj = new Circle();
    // Call the virtual method
    Console.WriteLine(obj.WhoAmI());
    // Call the extension method
    Console.WriteLine(obj.WhoAmIEx());
}

public class Shape {
    public virtual string WhoAmI() {
        return "Virtual Shape";
    }
}
public class Circle : Shape {
    public override string WhoAmI() {
        return "Overriden Circle";
    }
}

public static class Extensions {
    public static string WhoAmIEx(this Shape obj) {
        return "Shape Extension";
    }
    public static string WhoAmIEx(this Circle obj) {
        return "Circle Extension";
    }
}

Running this produces:
 Overriden Circle
Shape Extension

Took me a little while to figure out this behavior (although I should have realized it from the start). I still ended up using an extension method to add one new call but after we merge the code I think I will change that back to a virtual method.

Wednesday, May 16, 2012

Fluent Smalltalk

The other week I wrote about creating HTML controls in ASP.NET MVC using the Fluent Interface pattern. I haven't been a Smalltalker since the 90s so it took awhile for it click where I had seen this pattern before. In Smalltalk the default return value from a message send (aka method) is the receiver (aka the object itself or 'self'). You are encouraged by the language to create readable chains of method sends.

I also had a thought about how the C# compiler could support this as a language level feature by allowing the 'this' keyword as the return type for a method.

So instead of having to write a method like:
public Image ImagePath(string path) {
  imagePath = path;
  return this;
}
You could just write:
public this ImagePath(string path) {
  imagePath = path;
}

Monday, May 7, 2012

Database table initialization

So how do you create, update and initialize the tables and data in your application's database. The product I currently work on supports both being installed locally by the customer or being hosted by us as a SaaS offerring. Additionally we support a customer using either Oracle or SQL Server as the backend database so we wanted our database initialization routines to be as database agnostic as possible (rather than using SQL scripts).

We've created classes and objects in C# that represent the tables and columns that the application uses. These classes generate the appropriate SQL needed to setup the database. The db setup code can be run to initialize a database from scratch or update an existing install to the lastest version. It also creates indexes and seeds the tables with the shipped data. To create a table we have code like:
    // Create a basic users table.
    DbTableBuilder table = new DbTableBuilder(dbType, "USERS", setupLog);
    table.AddKeyColumn("userid");
    table.AddCharColumn("username", 255);
    table.AddCharColumn("password", 50);
    table.AddCharColumn("email", 100);
    table.AddCharColumn("name", 100);
    table.CreateTable(connection);

    // Create an index on the username.
    index = new DbIndexStatement("IDX_USERS_NAME", "USERS", "username");
    index.CreateIndex(connection);

I've started experimenting with LINQ to SQL and the Entity Framework. It's nice how it will auto-create the tables (at least in SQL Server) but not sure the best way to seed the tables with shipped data or recreate both production and testing databases. I also ran across an open source project (but can't now find it again) that uses a JSON formatted file to specify the data table structure and used that to create the tables.

For now I think we will stick with the C# code but keep looking for other ideas.

Thursday, May 3, 2012

Fire and Forget Index Creation

Recently we added a new index that we realized was going to take a really long time to create on some of our existing tables with lots of data (it would of course be fine on new installs with no data). So we started to look for options to tell the database to create the index in the background and return control to the setup code (aka fire and forget). We didn't really care when the index creation finished as long as it did at some point.
using (SqlCommand cmd = sqlConnection.CreateCommand()) {
    cmd.CommandText = "CREATE INDEX index_name ON table_name (column_name)";
    connection.Open();
    cmd.BeginExecuteNonQuery();
}

This failed almost universally (a couple of indexes were created before the connection closed but basically it didn't work). As this similiar question in StackOverflow highlights, if the connection closes the query ends. We looked at implementing the ThreadPool option outlined in that question or just adding an EndExecuteNonQuery method to close the connection but both ran into a roadblock. Our Network Operations team runs the setup code from a Windows application. During testing we found that closing the Windows application also closed the connection meaning that the index creation fails. We could add a progress indicator to the application and have them wait to close the app but then we were essentially back to the blocking issue.

So somewhat relutcantly we decided to use SQL ServerAgent Service to create the indexes. The downside being if we wanted to do the same for Oracle we would have to write separate code (we work with both SQL Server and Oracle). It only works on SQL Server when the service is installed and running (which excludes SQL Server Express).

To kick off a job we added code similiar to the answer to this question. We also added the following test to see if SQL Agent is running otherwise we fallback to the old blocking code.

SELECT spid FROM MASTER.dbo.sysprocesses WHERE program_name = N'SQLAgent - Generic Refresher'

Ideally it would be nice if we could have just kicked this off from C# code but at least this allowed us to remove a roadblock and move on to the next issue.