- Posted by liammclennan on June 22, 2010
My rule of thumb for storing configuration settings is:
- if it does not need to change hard code it
- if it needs to change but the user of the application can’t change it, store it in the configuration file
- if the user can change it, store it in a database
This post discusses configuration data stored in the configuration file. For the examples that follow the configuration data might look like:
<appSettings>
<add key="ForumURLRoot" value="http://someurl" />
<add key="EmailSendingRetries" value="3" />
</appSettings>
To make my applications robust and testable I like to write a service that wraps appSettings. What I mean by robust is that it provides useful error data in the event that the application depends upon configuration data that is missing. My configuration service throws the following exception if an appSetting is missing:
A nice clear error message helps me to rapidly diagnose the problem.
This service is something that I have written many times. To be honest, there is often some copy and paste involved. Here is what the most recent incarnation looks like:
public interface IConfigService
{
string ForumURLRoot();
int EmailSendingRetries();
}
public class ConfigService : IConfigService
{
// an example configuration element
public string ForumURLRoot()
{
return ReadSetting("ForumURLRoot");
}
// an example with a cast
public int EmailSendingRetries()
{
return (int)ReadSetting("EmailSendingRetries");
}
private string ReadSetting(string key)
{
CheckForKey(key);
return ConfigurationManager.AppSettings[key];
}
private void CheckForKey(string appSettingKey)
{
if (ConfigurationManager.AppSettings[appSettingKey] == null
|| ConfigurationManager.AppSettings[appSettingKey].Equals(string.Empty))
{
throw new ConfigurationException("Missing appsetting: " + appSettingKey);
}
}
}
Providing a method for each configuration setting gives me:
- the ability to cast if the setting needs to be something other than string
- the ability to easily mock configuration settings for testing
Stubbing a setting, such as ForumURLRoot, is easily accomplished with Moq:
[Test]
public void ConfigMock()
{
var configMock = new Mock<IConfigService>();
configMock
.Expect(config => config.ForumURLRoot())
.Returns("http://google.com.au");
Assert.AreEqual("http://google.com.au", configMock.Object.ForumURLRoot());
}
I write this post to expose my ignorance. If I am doing to wrong, let me know.
- Posted by liammclennan on June 17, 2010
Just because I like to build things, and I like to learn, I have been working on a keyboard shortcut reference site. I am using this as an opportunity to improve my ruby and rails skills.
The first few days were frustrating. Perhaps the learning curve of all the fun new toys was a bit excessive. Finally tonight things have really started to come together. I still don’t understand the rails built-in testing support but I will get there.
Interesting Things I Learned Tonight
RubyMine IDE
Tonight I switched to RubyMine instead of my usual Notepad++. I suspect RubyMine is a powerful tool if you know how to use it – but I don’t. At the moment it gives me errors about some gems not being activated. This is another one of those things that I will get to. I have also noticed that the editor functions significantly differently to the editors I am used to. For example, in visual studio and notepad++ if you place the cursor at the start of a line and press left arrow the cursor is sent to the end of the previous line. In RubyMine nothing happens.

Haml
Haml is my favourite view engine. For my .NET work I have been using its non-union Mexican CLR equivalent – nHaml.
Multiple CSS Classes
To define a div with more than one css class haml lets you chain them together with a ‘.’, such as:
.span-6.search_result contents of the div go here

Indent Consistency
I also learnt tonight that both haml and nhaml complain if you are not consistent about indenting. As a consequence of the move from notepad++ to RubyMine my haml views ended up with some tab indenting and some space indenting. For the view to render all of the indents within a view must be consistent.
Sorting Arrays
I guessed that ruby would be able to sort an array alphabetically by a property of the elements so my first attempt was:
Application.all.sort {|app| app.name}
which does not work. You have to supply a comparer (much like .NET). The correct sort is:
Application.all.sort {|a,b| a.name.downcase <=> b.name.downcase}
MongoMapper Find by Id
Since document databases are just fancy key-value stores it is essential to be able to easily search for a document by its id. This functionality is so intrinsic that it seems that the MongoMapper author did not bother to document it. To search by id simply pass the id to the find method:
Application.find(‘4c19e8facfbfb01794000002’)
Rails And CoffeeScript
I am a big fan of CoffeeScript so integrating it into this application is high on my priorities. My first thought was to copy Dr Nic’s strategy. Unfortunately, I did not get past step 1. Install Node.js. I am doing my development on Windows and node is unix only. I looked around for a solution but eventually had to concede defeat… for now.
Quicksearch
The front page of the application I am building displays a list of applications.

When the user types in the search box I want to reduce the list of applications to match their search. A quick googlebing turned up quicksearch, a jquery plugin. You simply tell quicksearch where to get its input (the search textbox) and the list of items to filter (the divs containing the names of applications) and it just works. Here is the code:
$('#app_search').quicksearch('.search_result');
Summary
I have had a productive evening. The app now displays a list of applications, allows them to be sorted and links through to an application page when an application is selected. Next on the list is to display the set of keyboard shortcuts for an application.
- Posted by liammclennan on June 17, 2010
Visual studio supports relatively advanced string manipulation via the ‘Quick Replace’ dialog.
Today I had a requirement to modify some html, replacing line breaks with unordered list items. For example, I need to convert:
Infrastructure<br/>
Energy<br/>
Industrial development<br/>
Urban growth<br/>
Water<br/>
Food security<br/>
to:
<li>Infrastructure</li>
<li>Energy</li>
<li>Industrial development</li>
<li>Urban growth</li>
<li>Water</li>
<li>Food security</li>
This cannot be done with a simple search-and-replace but it can be done using the Quick Replace regular expression support. To use regular expressions expand ‘Find Options’, check ‘Use:’ and select ‘Regular Expressions’
Typically, Visual Studio regular expressions use a different syntax to every other regular expression engine. We need to use a capturing group to grab the text of each line so that it can be included in the replacement. The syntax for a capturing group is to replace the part of the expression to be captured with { and }. So my regular expression:
{.*}\<br/\>
means capture all the characters before <br/>. Note that < and > have to be escaped with \.
In the replacement expression we can use \1 to insert the previously captured text. If the search expression had a second capturing group then its text would be available in \2 and so on. Therefore, the required replacement expression is:
<li>\1</li>
Visual Studio’s quick replace feature can be scoped to a selection, the current document, all open documents or every document in the current solution.
- Posted by liammclennan on June 14, 2010
After more time than I care to admit I have finally released a rudimentary Http Handler for serving compiled CoffeeScript from Asp.Net applications.
It was a long and painful road but I am glad to finally have a usable strategy for client-side scripting in CoffeeScript.
Why CoffeeScript?
As Douglas Crockford discussed in detail, Javascript is a mixture of good and bad features.
The genius of CoffeeScript is to treat javascript in the browser as a virtual machine.
By compiling to javascript CoffeeScript gets a clean slate to re-implement syntax, taking the best of javascript and ruby and combining them into a beautiful scripting language. The only limitation is that CoffeeScript cannot do anything that javascript cannot do.
Here is an example from the CoffeeScript website. First, the coffeescript syntax:
reverse: (string) ->
string.split('').reverse().join ''
alert reverse '.eeffoC yrT'
and the javascript that it compiles to:
var reverse;
reverse = function(string) {
return string.split('').reverse().join('');
};
alert(reverse('.eeffoC yrT'));
Areas For Improvement ;)
The current implementation is deeply flawed, however, at this point I’m just glad it works. When the server receives a request for a coffeescript file the following things happen:
- The CoffeeScriptHandler is invoked
- If the script has previously been compiled then the compiled version is returned.
- Else it writes a script file containing the CoffeeScript compiler and the requested coffee script
- The process shells out to CScript.exe to to execute the script.
- The resulting javascript is sent back to the browser.
This outlandish process is necessary because I could not find a way to directly execute the coffeescript compiler from .NET. If anyone can help out with that I would appreciate it.
- Posted by liammclennan on June 12, 2010
- Posted by liammclennan on June 12, 2010
The mouse is like computer training wheels. It makes using a computer easier – but it slows you down.
Like many of my peers I am making a effort to learn keyboard shortcuts to reduce my dependence on the mouse. So I have started accumulating browser bookmarks to websites listing keyboard shortcuts for vim and resharper etc.
Based on the assumption that I am not the only person who finds this untenable I am considering building the ultimate keyboard shortcut reference site. This is an opportunity for me to improve my rails skills and hopefully contribute something useful to the anti-mouse community.
Mockups
Shortcuts will be grouped by application, so the first thing a user needs to do is find their application. They do this by typing the application name into a textbox and then selecting from a reducing list of applications. This interface will work like the stackoverflow tags page.
Selecting an application will take the user to a page that lists the shortcuts for that application. This page will have a permalink for bookmarking. Shortcuts can be searched by keyword or by using the shortcut.

- Posted by liammclennan on June 11, 2010
Rake is a ruby internal DSL for build scripting. With (or without) the help of albacore rake makes an excellent build scripting tool for .NET projects.
The albacore documentation does a good job of explaining how to build solutions with rake but there is nothing to assist with another common build task – updating configuration files.
The following ruby script provides some helper methods for performing common configuration changes that are required as part of a build process.
class ConfigTasks
def self.set_app_setting(config_file, key, value)
ovsd_element = config_file.root.elements['appSettings'].get_elements("add[@key='#{key}']")[0]
ovsd_element.attributes['value'] = value
end
def self.set_connection_string(config_file, name, connection_string)
conn_string_element = config_file.root.elements['connectionStrings'].get_elements("add[@name='#{name}']")[0]
conn_string_element.attributes['connectionString'] = connection_string
end
def self.set_debug_compilation(config_file, debug_compilation)
compilation_element = config_file.root.elements['system.web'].get_elements("compilation")[0]
compilation_element.attributes['debug'] = false
end
private
def self.write_xml_to_file(xml_document, file)
File.open(file, 'w') do |config_file|
formatter = REXML::Formatters::Default.new
formatter.write(xml_document, config_file)
end
end
end
To use, require the file and call the class methods, passing the configuration file name and any other parameters.
require 'config_tasks'
ConfigTasks.set_app_setting 'web.config', 'enableCache', 'false'
- Posted by liammclennan on June 11, 2010
I like this capture because it reminds me of the ‘England Prevails’ dialog from V for Vendetta.

- Posted by liammclennan on June 10, 2010
For years now we have been hearing from 37 signals that the way to bake a great web app is to build less – well the same is true of pizza.
Our western hedonism has led us to pursue ever cheesier and more stuffed crusts at the expense of the simple flavours. All we are left with is a fatty, salty heart attack in waiting.
The Italians know that the secret to great taste is simplicity. With that in mind I decided to base my pizza masterpiece on these simple flavours:
- tomato
- sopressa (spicy aged salami)
- mozzarella
- garlic
- basil
Of course the first thing one needs when making pizza is a base.
A freshly made base is extremely important but unfortunately I was too lazy.
Next up is the tomato sauce. My wife made the sauce by reducing some tomatoes and adding herbs and sugar.
We had selected some fine ingredients to make our topping: sopressa salami, fresh basil and the best mozzarella we could find.
It is, according to google, important to bake pizza at a high temperature, so I set the oven to 250C (480F).
Here are the before and after shots:
Meanwhile, the dog did nothing.

- Posted by liammclennan on June 3, 2010
Lately I have been using the windows console a lot. I find that I often need a number of console windows open at once. The regular windows console does not handle this well.
Console2 is a more advanced console for windows. It has a tabbed interface and a number of other nice features. It supports alpha transparency if you have Mac envy, it has improved text selection and copy/paste and it is far more customizable than the default console.
If you look in the background of the above image you can see this post. Now you know what the matrix is.