Archive for category Software Development

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: , ,

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: ,

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: , ,

What's up with the Tadmap project?

If you’ve been following the Tadmap blog then you might be wondering why there haven’t been any updates since November. Well here’s why.

Before Christmas I decided to try out the new ASP.Net MVC framework, for no other reason than wanting to learn more about it. My initial impression was that it would be ideal for Tadmap, so I decided to go for it. The change over meant refactoring all the pages I already had into controller and views, and I got 90% there very quickley. As I had never used MVC before I started following Rob Conery’s MVC Storefront series to make sure I was doing things right. This may or may not have been a mistake.

First, he was using a fancy new version of the Repository pattern which I liked the look of very much, this lead to even more refactoring and learning more about LINQ on the way.

I tried to ignore the Test Driven Development aspect of what Rob was doing, but eventually I downloaded Nunit just to try my hands at writing an automated test. Straight away I was hooked on TDD. I tried limiting TDD to just new code but to make the new code testable meant refactoring the old code to reduce dependencies.

It’s taken a lot longer then I wanted but I am having a lot of fun doing it. My code is clean and loosely coupled and I have over a hundred unit tests and a bunch of integration tests that I can fire with one click.

Even though I have no boss and as yet no users, I have still run into the age old problem of doing it right versus getting it done. There is the ultimate balance to be made between making things perfect while achieving the goals and real world features that help our moral and motivation. It’s starting to bother me that I haven’t been able to add any new features in over a month.

So in the next few weeks I hope to get an, albeit imperfect, ASP.Net MVC version of the application up on the live server. I’ll then be in a position to iron out the last few post refactoring bugs or implement a cool new feature when I need the motivation to keep going.

Tags: , , ,

ASP.Net MVC on Blacknight

Update: SP1 is now installed for ASP.Net 3.5. So now the only DLL you need to upload is ‘System.Web.Mvc.dll’.

I was reading a little bit about the new ASP.Net MVC stuff. I think it would be ideal for my Tadmap (image hosting) project. Before I started any major development re-work I needed to check that my hosting provider, Blacknight, could host it.
So I uploaded the sample MVC application. Of course it didn’t work at first but I don’t give up that easily and it is now up and running. I think the following steps will work for anybody else trying the same.
As Blacknight do not have SP1 installed for ASP.Net 3.5 you have to upload the new DLLs when you deploy. Simple instructions can be found here, Bin Deploying ASP.NET MVC.

My windows account on Blacknight is using IIS 6.0 which does not automatically support MVC. In order to handle URLs the MVC way you will need to follow the instructions here, ASP.NET MVC on IIS 6 Walkthrough. Basically, you just need to grab the code for the Global.asax.cs file and add a ‘.mvc’ file mapping using your Blacknight control panel.
To add the file mapping, just go to the ‘Web’ tab of your domain and add ‘mvc’ to the ASP.Net 2 mappings. It should look like the image below and make sure that ‘Script Engine’ is ‘On’ and ‘Verify File Exists’ is ‘Off’.

One small (cosmetic) problem is that the URLs aren’t as clean as they should be because the ‘mvc’ extension is needed. So the URL for the About action of the Home controller that should look like ‘http://trevorpower.com/Home/About‘ instead looks like ‘http://trevorpower.com/Home.mvc/About‘. I have seen solutions to this problem as well but that’s for another day. Right now I have the not so small task of converting an existing ASP.Net application to an ASP.Net MVC application.

Tags: , ,