Displaying the workspace name in Visual Studio 2008

Switching between Visual Studio instances with different workspaces can be very frustrating as it is hard to tell which workspace solution is open. I was planning on writing a plug-in to display the workspace name in the title bar when I found this question on Stackoverflow by someone with a similar problem, Working with different versions/branches of the same Visual Studio 2005 solution.

One of the comments there suggested the use of ‘hard links’ to the solution file. I have given it a go and it has been working quite well for me for that last few days. Here’s how to do it.

A normal windows shortcut will not suffice, you need to create a symbolic or hard link to the solution file. In Windows 7 you can do this via the command line tool mklink. If you have a workspace called ‘Merge’ and a solution called ‘MyApp.sln’ the the following command will create a shortcut that you can use. (You will need to run this as an administrator).

C:\MyApp>mklink MyApp.Merge.sln MyApp.sln

Multiple Visual Studio Instances

Now use the new link to open you solution file. Then when you have multiple VS instances open and you click on the Visual Studio task bar icon, you will see the name of your new link (including workspace name or branch name). It also appears in the main title bar.

Have you come across any better solutions? Or easier ways to create links?

Update: I wasn’t sure at first what the difference would be between a hard link and a symbolic link but it turns out that using a hard link (a ‘/H’ switch on the above command) helps when you need to save changes to the solution file. But I suggest opening the solution file normally when you need to modify it as saving the solution from the hard link will insert its name into the file.

Tags: , ,

Wickes 1 – 0 Maplin

I was in a Maplin store yesterday returning a set of precision screw drivers that were of such poor quality that I asked to see the manager to complain. I showed the manager where it said “Quality Tools” on the box then I showed him how the tiny shafts just rotated in the handles and came off. I showed how the ones that didn’t fall apart weren’t even straight (so crooked that they couldn’t be used).

They were so bad that I was expecting a “wow, I’ll have to take them off the shelves straight away”. But what I got was:

Yeah, they’re pretty bad but we didn’t make them.

I was told that any complaints should be addressed at the manufacturer!

On a positive note I stopped in Wickes (recommended by a friend) on my way home and picked up a set of precision screw drivers for around the same price.

They were Wickes own brand so I wasn’t expecting much but the quality was far superior to what I got from Maplin. Even the plastic case they came in was sturdy and practical. So if you’re in the Limerick area and looking for good value tools I can recommend Wickes.

Sharing configuration settings in Visual Studio

Correctly managing your systems settings during both development and deployment can save you a lot of time. When ever you have to manually change settings there is the opportunity to mess up, so I try to automate any repetitive configuration tasks.

It often happens that application settings or connection strings are needed by more than one component in your system. The solution I use is a variation of this method of sharing app.config files between applications, except that it allows each project to have its own app.config or web.config files which reference the common settings.

Creating shared settings

The first step is to make a settings class that acts as a wrapper around the values in the configuration files. This is a very simple class inheriting ApplicationSettingsBase and looks like this:

using System.Configuration;

namespace TP.Example.Configuration
{
    public class Settings : ApplicationSettingsBase
    {
        private static Settings _defaultInstance =
                (Settings)(ApplicationSettingsBase.Synchronized(new Settings()));

        public static Settings Default { get { return _defaultInstance; } }

        [ApplicationScopedSettingAttribute()]
        string ServiceName
        {
            get { return ((string)(this["ServiceName"])); }
            set { this["ServiceName"] = value; }
        }

        [ApplicationScopedSettingAttribute()]
        string EventLogName
        {
            get { return ((string)(this["EventLogName"])); }
            set { this["EventLogName"] = value; }
        }

        [ApplicationScopedSettingAttribute()]
        [SpecialSettingAttribute(SpecialSetting.ConnectionString)]
        string ConnectionString
        {
            get { return ((string)(this["ConnectionString"])); }
            set { this["ConnectionString"] = value; }
        }
    }
}

The next step is to create the files that contain the settings. I usually have two, one for application settings and one for connection strings. The application settings file consists of a single node matching the full name of my settings class:

<TP.Example.Configuration.Settings>
  <setting name="ServiceName" serializeAs="String">
    <value>My Example Service
  </setting>
  <setting name="EventLogName" serializeAs="String">
    <value>ExampleLogName
  </setting>
</TP.Example.Configuration.Settings>

The connection strings file consists of one ‘connectionStrings’ node. Note the name of the connection string is qualified with the full name of my settings class.

<connectionStrings>
  <add name="TP.Example.Configuration.Settings.ConnectionString" connectionString="[...]" />
</connectionStrings>

These files should exist outside any of your projects but be under source control. I usually put them in a solution folder ‘Configuration’ that contains a simple project with the above settings class:
'Configuration' solution folder

Referencing shared settings

FilesAsLinksThese common settings are now ready to be used by any project in the solution by following these steps:

  1. Add a reference to the settings project.
  2. Add a link to settings files and turn on ‘copy to output directory’
  3. Include settings files in the app.config/web.config

To link to the settings files you should Add -> Existing Item -> Add As Link, they will then appear with a shortcut icon. This means that they only point to the original file, so there is no duplication.

Now that the files are in our project we just need to get our App.config file to include them. A simplified App.config would look like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup" >
      <section name="TP.Example.Configuration.Settings" type="System.Configuration.ClientSettingsSection" />
    </sectionGroup>
  </configSections>
  <connectionStrings configSource="TP.Example.Configuration.ConnectionStrings.config" />
  <applicationSettings>
    <TP.Example.Configuration.Settings configSource="TP.Example.Configuration.AppSettings.config" />
  </applicationSettings>
</configuration>

Now when you modify one of these files the change will be picked up by all other projects in the solution.

Websites and Web.config

Using these settings in a website requires one extra step. As before, the settings file will be linked to by the project file and the ‘Copy to Output Directory’ turned on. The problem is that the web.config file is usually at the root while the output directory is ‘bin’ or ‘bin/Debug’ depending on your setup. Because the output folder can depend on the build configuration, I have found the best solution is to copy the config files from the target directory to the project directory. This is just one line in the build events.COPY $(TargetDir)*.config $(ProjectDir)
Writing it out like this sounds like a lot of work but it is easy to setup and easy to maintain. If you have any question or have a better solution, please leave a comment.

Tags: , , ,

Enumerations and global constants in SQL Server

Everybody knows that you shouldn’t put lots of business logic into stored procedures, right? Well maybe not, but whether or not you agree with this statement you’ll always find some cases where it just makes things easier or more efficient to have your business rules close to the data. Often business rules mean dealing with record types, flags and other magic numbers. These numbers normally correspond to enumerations or constants in our favourite high level language (for me C#).

So what do we do with all these magic numbers? Of course, we being good programmers, put them into well named variables that makes the code easier to read and the values easier to maintain. But what happens when we have multiple stored procedures using the same values?

I didn’t know the answer to this, so I put a question on Stack Overflow, What are the different ways of handling ‘Enumerations’ in SQL server? I got some good answers, but most did some mapping between VARCHARs and INTs. Hard coded strings are better than hard coded numbers because they are easier to read, but they have other problems such as hard to find typos.

One answer that wasn’t given, and hasn’t been suggested by any other developers I’ve talked to, is the use of scalar functions as constants. I stumbled on this solution today while refactoring some existing functions and ended up with a function that did little more than call another function with a hard coded int value. You can create a simple function that just returns a number:

CREATE FUNCTION COLOR_RED()
RETURNS INT
AS
BEGIN
	RETURN 2
END

This is quite a lot of code for just one constant but it is available to all stored procedures. Maybe they could be generated automatically?

As for performance, I haven’t been able to write a test with any big difference in execution time, but I’m sure there must be some hit. Regardless it is bound to perform better than most of the other answers I got for the initial question.

One problem I have found is that you cannot pass them directly to other stored procedures, you need to introduce an intermediate variable, a bit annoying but not a show stopper.

Maybe you’ve being doing this all the time? If there’s something I’m missing, please leave a comment.

Tags:

Using the IIS SEO Toolkit

Was at a great talk by Scott Guthrie today in Dublin. One thing he talked about near the end was the new IIS SEO Toolkit, this I was able to try as soon as I came home.

It was very easy to install and can be pointed at any website (not just your own). To install:

  • If you haven’t already, get the Web Platform Installer.
  • Select and install the ‘Search Engine Optimization Toolkit’.

Then, to examine a site:

  • Start ‘Internet Information Services (IIS) Manager’.
  • Go to Search Engine Optimization -> Site Analysis.
  • Point it at any website.

Starting a Site Analysis of my blog
It then gives you a list of of rule violations, 405 for my blog. The details of  each violation include a description of the rule with recommended action.
SEO Toolkit results for my website
As you can see, rule violations include broken links, missing description text and non-relevant link text (as in click here). Most of these rules are obvious but they are hard to spot without looking at the generated HTML of the page.

Tags: , ,

Software Craftsmanship

Most developers I’ve worked with would have come to me at some point and asked questions like:

  • What is the best way to implement this new feature?
  • What do you think of this design, is it good enough?

This to me indicates that software developers in general do take pride in their work and try to achieve the first part of the Manifesto for Software Craftsmanship:

Not only working software, but also well-crafted software

Given that most developers are competent enough to come up with good designs and implement them well with nice clean code and generally have the desire to do so, why is this rarely reflected in the resulting code?

The reason, I believe, is related to the second line from the same manifesto:

Not only responding to change, but also steadily adding value

The key word here being change. In contrast to my first observation, many developers when working with existing code will try and squeeze in their fix/feature and get out as quickly as possible. If they do come to me to talk about that change it’s just to grumble and complain about how hard it is to work with that code or how buggy it is.

The next time someone grumbles about some code they are working on I will remind them (or myself) that because they are now working on that code it is now their responsibility, it is up to them to make it better. If you’re not happy with the code you are working with, think about how the existing code could be changed to make your fix/feature easier to add.

If you’re not making the code base better, you are making it worse!

Tags: ,

Finally got my Android


I’ve had my HTC Hero for a few weeks now and I have to say it’s fantastic. I’ve never owned an iPhone or other smart phone so I can’t really give a proper review but I’ll make a few points.

The first thing that strikes me is that the user interface looks shiny and sleek but is also very practical.

I know other phones already do this but putting widgets on the home screen is a great way to customize the phone, you spend a lot less time scrolling through menus and lists. Apart from the standard clock/weather type widgets I use the twitter client widget and some of the on/off widgets for wifi, bluetooth, GPS etc.

One feature I really like is that when I add a contact I can select that person from my facebook and flickr friends, it will then use that persons facebook avatar and date of birth if available.

Although it comes with it’s own twitter application called Peep it doesn’t integrate twitter into the phone in the same way that it does with facebook and flickr. For example when I select a contact I can easily see their facebook/flickr updates and photos. I would’ve liked to see the same support for twitter (or even better, arbitrary person related data via third party plugins).

You could say a phone is only as good as the available apps, and this is a little problem for Irish users because paid apps are not yet available on the market place. But this is surely to change soon. In the meantime there are lots of free apps to play around with and it also comes with some nice apps pre installed like google maps and youtube.

With regard to using it in Ireland I have had no other problems except that O2 weren’t able to help setup the 3G settings. I eventually found the correct APN settings but MMS message are working for me at the moment, apparantly these settings work for both 3G and MMS but I haven’t tried them myself.

The only real problem I’ve had so far was with my home wifi, where I would connect successfully but about 30 seconds later it would drop the connection. I had to fiddle with my router’s wireless settings a lot until the phone’s wifi connection was more stable.

All the early reviews of the phone said that the phone was a bit sluggish, and I have to agree. While scrolling and sliding things around the screen it doesn’t always go smoothly.

But I’m using it quite happily and it seems that there is even a software update on the way that will help the performance.

Tags: , , ,

A limitation of shared hosting and a push toward cloud computing

Today I ran into one of the limitations of shared hosting.

I’ve been struggling for the last few weeks to handle large files in my application. I published to the server earlier this week but with no success. All my tests failed after 10 minutes with a ‘Request timed out’ error. I was testing with an 80mb file but with a slow broadband connection (thanks to Ice). I had increased the timeout and max request length for the upload handler like so in the web.config:

   <location path="Upload.mvc/Upload">
      <system.web>
         <httpRuntime  maxRequestLength="2097151" executionTimeout="10800" />
      </system.web>
   </location>

I ruled out any setting that I had control over, so the next step was to talk to my hoster, Blacknight, to see if they could help me out. They replied saying that they could not support the uploading of large files stating that:

It ties up too much system resources to upload huge files like that through asp and would cause problems for other users on the shared server.

Of course they’re right and I can’t really complain but it’s bitterly disappointing none the less.

For the foreseeable future, a couple of file uploads a month is all I require so I don’t want to pay for more expensive hosting packages. So back to the drawing board…

Cloud computing

I’m already using the Amazons S3 service for the storage of the images and I think I can upload directly from the client to S3. So I just need a high spec PC for a few minutes to process the files after the user has uploaded them. Once processed I will only ever have to deal with smaller versions or tiled sections. This looks like an ideal candidate for the Amazon Elastic Compute Cloud (EC2). Where I can pay by the hour for a high spec machine.

I was hoping to dip my toe into some cloud computing at some point but I didn’t want to be pushed. This is going to be a lot more work than I hoped and will need some effort just to cordinate between the web server, client machine and a cloud computer.

I haven’t decided on the final architecture yet, just thinking out loud, but looks like a lot of fun (and hard work) ahead…

Tags: , , , , ,

Handling multiple Web.config files in Visual Studio

I use different settings for my application when it is running on the live server and when it is running on my development machine. To manage this I name my config files using the target name like so:

  • Web.Debug.config
  • Web.Release.config

Adding the following to the project file will cause MSBuild to automatically copy the correct file to ‘Web.config’ when you build the project in Visual Studio. In my case the ‘BeforeBuild’ target was already in the project file but commented out, I just needed to add the copy task and related items.

<Target Name="BeforeBuild">
   <ItemGroup>
   <ConfigSourceFiles Include="Web.$(Configuration).config" />
   <ConfigDestinationFiles Include="Web.config" />
   </ItemGroup>
   <Copy
      SourceFiles="@(ConfigSourceFiles)"
      DestinationFiles="@(ConfigDestinationFiles)"
   />
</Target>

So I select the right target from the toolbar and build/publish and the correct settings are used.

Where possible, to avoid duplicating settings, I create separate config files and point the main config files at it using the configSource attribute. For example the page settings for debug and release are the same so my pages element in both files look like this:

   <pages configSource="Configuration\System.Web\pages.config" />

Before implementing this I was manually changing or copying the config files before deploying to my server, so I hope this will help someone else save a bit of time.

Tags: , ,

Not mocking the HttpContext?

Someone asked me a question recently about mocking, and I had to say I didn’t have much experience with it. I found this answer a bit odd myself as I’ve been doing a lot of TDD with an ASP.Net MVC application. I’d seen lots of people talking about mocking the HttpContext and wondered “Why haven’t I had to do this?”.

The first time I started TDD, I was working on converting an existing ASP.Net application to ASP.Net MVC. Most of my controller actions checked the current security principle in the context, so I immediately ran into problems when trying to test these.
I didn’t know much about MVC or TDD so used what I did know. I knew about a powerful component of MVC called an action invoker, that could be overridden to handle some parameter stuff. I found that I could easily create an ActionInvoker that would populate parameters of a certain type (namely IPrincipal) using the following code:
public class ActionInvoker : ControllerActionInvoker
{
   protected override object GetParameterValue(System.Reflection.ParameterInfo parameterInfo)
   {
      if (parameterInfo.ParameterType == typeof(IPrincipal))
         return HttpContext.Current.User;

      return base.GetParameterValue(parameterInfo);
   }
}

And put the following into my controller constructors:
public MyController()
{
   ActionInvoker = new ActionInvokers.ActionInvoker();
}
This made it easy to test my controller actions. I just needed to mock a simple IPrincipal. I used a similar solution when my file upload controller needed access to HttpContext.Current.Request.Files.
At the moment my code only depends on a few simple objects that come from the HttpContext and not the context itself. Surely this is better, if not please comment. I’m going to change the above to conform with everyone else by mocking the HttpContext but the only reason I see for doing this, is that the above action invoker is not testable. Is this the only reason?
Before you point it out to me, I have recently moved most of my security code into AuthorizeAttributes. Now my unit tests for invalid calls (security wise) to controller actions all fail but that’s for a future post.

Tags: , ,