Using Contracts to discover Liskov Substitution Principle Violations in C#

In his book Agile Principles, Patterns, and Practices in C#, Bob Martin talks about using pre- and post-conditions in Eiffel to detect Liskov Substitution Principle violations. At the time he wrote that C# did not have an equivalent feature and he suggested ensuring that unit test coverage was used to ensure the same result. However, that does not ensure that checking for LSP violations are applied consistently. It is up to the developer writing the tests to ensure that they are and that any new derived classes get tested correctly. Contracts, these days, can be applied to the base class and they will automatically be applied to any derived class that is created.

Getting started with Contracts

If you’ve already got Visual Studio set up to check contracts in code then you can skip this section. If you don’t then read on.

1. Install the Code Contracts for .NET extension into Visual Studio.

2. Open Visual Studio and load the solution containing the projects you want to apply contracts to.

3. Open the properties for the project and you’ll see a new tab in the project properties window called “Code Contracts”

4. Make sure that the “Perform Runtime Contract Checking” and “Perform Static Contract Checking” boxes are checked. For the moment the other options can be left at their default values. Only apply these to the debug build. It will slow down the application while it is running as each time a method with contract conditions is called it will be performing runtime checks.

Visual Studio Project Properties

You are now ready to see code contract issues in Visual Studio.

For more information on code contracts head over to Microsoft Research’s page on Contracts.

Setting up the Contract

Using the Rectangle/Square example from Bob Martin’s book Agile Principles, Patterns and Practices in C# here is the code with contracts added:

public class Rectangle
{
    private int _width;
    private int _height;
    public virtual int Width
    {
        get { return _width; }
        set
        {
            Contract.Requires(value >= 0);
            Contract.Ensures(Width == value);
            Contract.Ensures(Height == Contract.OldValue(Height));
            _width = value;
        }
    }

    public virtual int Height
    {
        get { return _height; }
        set
        {
            Contract.Requires(value >= 0);
            Contract.Ensures(Height == value);
            Contract.Ensures(Width == Contract.OldValue(Width));
            _height = value;
        }
    }
    public int Area { get { return Width * Height; } }
}

public class Square : Rectangle
{
    public override int Width
    {
        get { return base.Width; }
        set
        {
            base.Width = value;
            base.Height = value;
        }
    }

    public override int Height
    {
        get { return base.Height; }
        set
        {
            base.Height = value;
            base.Width = value;
        }
    }
}

The Square class is in violation of the LSP because it changes the behaviour of the Width and Height setters. To any user of Rectangle that doesn’t know about squares it is quite understandable that they’d assume that setting the Height left the Width alone and vice versa. So if they were given a square and they attempted to set the width and height to different values then they’d get a result from Area that was inconsistent with their expectation and if they set Height then queried Width they may be somewhat surprised at the result.

But there are now contracts in place on the Rectangle class and as such they are enforced on Square as well. “Contracts are inherited along the same subtyping relation that the type system enforces.” (from he Code Contracts User Manual). This means that any class that has contracts will have those contracts enforced in any derived class as well.

While some contracts can be detected at compile time, others will still need to be activated through a unit test or will be detected at runtime. Be aware, if you’ve never used contracts before that the contract analysis can appear in the error and output windows a few seconds after the compiler has completed.

Consider this test:

[Test]
public void TestSquare()
{
    var r = new Square();
    r.Width = 10;

    Assert.AreEqual(10, r.Height);
}

When the test runner gets to this test it will fail. Not because the underlying code is wrong (it will set Height to be equal to Width), but because the method violates the constraints of the base class.

The contract says that when the base class changes the Width the Height remains the same and vice versa.

So, despite the fact that the unit tests were not explicitly testing for an LSP violation in Square, the contract system sprung up and highlighted the issue causing the test to fail.

 

Running an ASP.NET MVC application on a fresh IIS8 install

IIS has ever increasing amounts of security, you can’t publish a basic ASP.NET MVC website anymore and expect IIS to host it without some additional work. The default config settings that the MVC uses are locked down in IIS, so it issues an error when you try to navigate to your fresh site.

Initially you may get a screen that says something bland and non-descriptive, like “Internal Server Error” with no further information.

To get the more detailed error messages modify your web application’s web.config file and add the following line to the system.webServer section:

<httpErrors errorMode="Detailed" />

Now, you’ll get a more detailed error message. It will look something like this:

The key to the message is: This configuration section cannot be used at this path. This happens when the section is locked at a parent level. Locking is either by default (overrideModeDefault="Deny"), or set explicitly by a location tag with overrideMode="Deny" or the legacy allowOverride="false".

The “Config Source” section of the error message will highlight in red the part that is denied.

In order to allow the web.config to modify the the identified configuration element you need to find and modify the ApplicationHost.config file. It is located in C:\Windows\System32\inetsrv\config. You’ll need to be running as an Administrator level user in order to modify the file.

Find the section group the setting belongs to, e.g.

<sectionGroup name="system.webServer">

Then the section itself:

<section name="handlers" overrideModeDefault="Deny" />

And update overrideModeDefault to "Allow" in order to allow the web.config to override it.

When you refresh the page for the website the error will be gone (or replaced with an error for the next section that you are not permitted to override)

Tip of the day: Quickly finding commented out code in C-like languages

This is a quick rough-and-ready way of finding commented out code in languages like C#, C++, javaScript and Java. It won’t find all instances, but it will probably find most.

Essentially, you can use a regular expression to search through the source code looking for a specific pattern.

The following works for Visual Studio for searching C#. The same expression would also likely work in other similar languages where the comment line starts with a double slash and ends in a semi-colon.

So for Visual Studio, press Ctrl+F to bring up the search bar, set the search option to be be “Regular Expression” and set it to look in the “Entire Solution” (or what ever extent you are searching) then enter the regular expression into the search box:

^\s*//.*;\s*$
Visual Studio 2012 Search Bar

Visual Studio 2012 Search Bar

Then tell it to “Find all” and you’ll be presented with a list of lines of code that appear to be commented out.

Caveats

It is not fully proof. It does not find code commented out in the style:

/*
* Commented = out.code.here();
*/

It also does not find commented out code on lines that do not end in a semi-colon such as namespace, class, method declarations and the like, nor on lines that simple contain scope operators (The { and } braces to define the scope of a namespace, class, method, etc.)

And although I’ve said C-like languages in the title, I don’t recall that C ever had the double-slash comment style (although many languages based on it do, hence “C-like”)

Update: Updated the regular expression to ignore white space at the start and end of the line.

DROP/CREATE vs ALTER on SQL Server Stored Procedures

We have a number of migration scripts that modify the database as our applications progress. As a result we have occasion to alter stored procedures, but during development the migrations may be run out of sequence on various test and development databases. We sometimes don’t know if a stored procedure will exist on a particular database because of the state of various branches of development.

So, which is better, dropping a stored procedure and recreating it, or just simply altering the existing one, and if we’re altering it, what needs to happen if it simply doesn’t exist already?

DROP / CREATE

This is the code we used for the DROP/CREATE cycle of adding/updating stored procedures

IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'MyProc')
BEGIN
       DROP PROCEDURE MyProc;
END
GO
 
CREATE PROCEDURE MyProc
AS
	-- Body of proc here
GO

CREATE / ALTER

We recently changed the above for a new way of dealing with changes to stored procedures. What we do now is detect if the procedure exists or not, if it doesn’t then we create a dummy. Regardless of whether the stored procedure previously existed or not, we can now ALTER the stored procedure (whether it was an existing procedure or the dummy one we just created

That code looks like this

IF NOT EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'MyProc')
BEGIN
       EXEC('CREATE PROCEDURE [dbo].[MyProc] AS BEGIN SET NOCOUNT ON; END')
END
GO
 
ALTER PROCEDURE [dbo].[MyProc]
AS
	-- Body of proc here
GO

This looks counter-intuitive to create a dummy procedure just to immediately alter it but it has some advantages over drop/create.

If an error occurs with drop/create while creating the stored procedure and there had been a stored procedure to drop originally you are now left without anything. With the create/alter in the event of an error when altering the stored procedure the original is still available.

Altering a stored procedure keeps any security settings you may have on the procedure. If you drop it, you’ll lose those settings. The same goes for dependencies.

Tip of the day: Forcing a file in to your Git repository

Normally, you’ll have a .gitignore file that defines what should not go into a git repository. If you find that there is a file or two that is ignored that you really need in the repository (e.g. a DLL dependency in a BIN folder for some legacy application that doesn’t do NuGet, or other package management) then you need a way to force that into Git.

The command you need is this:

git add --force <filename>

Replace <filename> with the file that you need to force in. This will force stage the file ready for your next commit.

You can also use . in place of a file name to force in an entire directory, or you can use wild cards to determine what is staged.

Afterwards you can use

git status

to see that it has been staged.

Recruitment Agents take note

A few times a week I get emails from recruitment agencies, they are are pretty much all along the same lines. The email seems to be a standard template that tells me absolutely nothing of importance about the job and gives me next to zero incentive to find out more.

I’m in a pretty great job at the moment that I’m really enjoying, so I’m not actually looking to move, but had this been maybe about a year ago (before things got restructured) I would have moved if anyone gave me a reasonable incentive for doing so. Based on the generic emails that say nothing of consequence that recruitment agents send out it is better the devil you know than the devil you don’t know. And I really don’t know.

So, here’s an example of something I received earlier this week:

From: <Name-of-agent>
Sent: <date>
To: Colin Mackay
Subject: Possible Synergy

Hi Colin,

We’ve not spoken before, I’m a head-hunter in the <technology-misspelled> development space and your name has came to light as a top talent in the <technology-misspelled> space.

I know your not actively on the market and I would not be contacting you if I didn’t feel I had something truly exceptional.

My role not only gives you interesting programme work in the <technology-misspelled> space but also strong career progression route in a growing business, work life balance, supportive environment, stability and a final salary pension. <name-of-city-I-live-in> based role.

Are you free for a discreet chat about this, what is the best time and number to call you on?

Kind Regards,

<name-of-agent>

<contact details>

This tells very little. She has at least identified that I work with the relevant technology (although sometimes I think that might just be a fluke given the number of emails I receive about things that I’m not remotely competent in) and the city I live in, so I suppose that’s a good start.

Pretty much every recruitment agent send out something similar. Every email I receive says the job is “truly exceptional”, “exciting” or that it’s an “amazing opportunity”. Those words are so over used that more often the email gets binned at that point. A lesson from many a primary school teacher trying to improve her pupils vocabulary is that they can’t use the word “nice” any more and they’ll get marked down if they do.

Nothing here sells me on the idea that change would be a good idea even although they acknowledged I’m not actively on the market.

The agent did not mentioned the type of company. Even if they can’t mention the name of the company at this stage the following would be useful: Is it a software consultancy? a digital agency? a software house with a defined product? An internal software department in a larger company? Which industry is the company operating in?

Some of the answers might turn me off, but it is better to know now than waste time to find out later. Some of the answers may pique my interest, which is obviously a good thing.

They mention the “<name-of-technology> space”. For the moment, we’ll ignore that it was misspelled (lots of technologies have strange ways of spelling or capitalising things, but it doesn’t take long to find out the official way).

They don’t really define what “XYZ space” actually means. There are so many subgroups of technology in that “space” that it could mean anything, including things I’m either unsuitable for or have no interest in. What’s the database technology (assuming there is one)? What is the front end technology (assuming there is one)? Or is the role wholly at one end or the other (e.g. mostly in the business logic or mostly in the front end)? What tool sets and frameworks are involved? (e.g. Visual Studio 2012, include version numbers. I’m interested in progressing forward, but if they’re still on Visual Studio 2008 I’m not interested and it would be better that you know that now). Is the company all single-vendor based (i.e. only using a tool if that vendor produced it) or do they use technologies from third parties (open source or commercial)?

There is nothing about training in the description they’ve provided. That would be a big bonus to me. I already spend in the region of £2000 a year keeping myself up-to-date (books, on-line videos, conferences, etc.), it would be nice to find an employer that is genuinely interested in contributing in that area beyond buying occasional books or giving me the occasional day-off outside of my annual leave to attend a conference that I’m already paying for. After all, they are the ones benefiting from all that training. However, occasionally emails do mention training, but it is sometimes couched in language that suggests a reluctance (e.g. “as an when required by the business”), but it’s there because the company or agent knows it will attract potential candidates if they mention training.

If the prospective company doesn’t provide training then I’d remind them that it is “Better to train your developers and risk they leave, than keep them stupid and risk they stay”. If the prospective company has a really negative view to training then I really wouldn’t want to work for them – I have already worked with a company that seemed to proactively provide disincentives for any sort of training.

Finally, there is no mention about salary. While, on the whole, I’m more interested in other things, I do have a mortgage to pay. If the salary won’t cover my bills with enough left over for a nice holiday (it’s no fun sitting at home watching Jeremy Kyle on days off) then that would be a showstopper even if all other things were perfect.

Also, stating salary as “£DOE” or “£market rate" is equally useless. Companies have a budget. They might say “£DOE” (depending on experience), but if it goes above their budget then that’s all they are going to offer. If that is not enough then it is better to know that up front than later on.

I’ve also been in situations where I’ve felt that the recruitment agent knew my salary expectation wasn’t going to fly with the hiring company, but strung me along for a bit until finally saying that they rejected my CV. It would be better to let potential recruits know up front without wasting everybody’s time.

While providing more information up front might reduce the interest from some potential candidates, at least they are not going to waste their valuable time and the recruitment agent’s valuable time pursuing something that is not going to come to anything. On the other hand, providing more information might be the catalyst to getting someone who is not actively looking to sit up and think about making that change.

Certainly, if I keep receiving the generic emails like the one above, especially that acknowledge I’m not actively looking, then I’m never going to look unless my current employer does something to make me question why I am there.

Injecting a Dependency into an IHttpModule with Unity

We’re starting a new project, and as part of that we want to get better at certain things. One is unit testing the things we didn’t last time around that were in hard-to-reach places. Pretty much most things that interact with ASP.NET have hard-to-reach places. Even ASP.NET MVC, which was supposed to be wonderful and much more unit testable that vanilla ASP.NET, has lots of places where this falls down completely. However, we’re gradually finding way to overcome these obstacles.

In this post, I’m going to concentrate on custom IHttpModule implementations.

We have a custom IHttpModule that requires the services of another class. It is already set up in our IoC container and we just want to inject it into the module we’re writing. However, modules are instantiated by ASP.NET before our IoC framework can get to it.

How I got around this was by creating an additional module (an InjectorModule) that wired up all the other modules that needed dependencies injected using Unity’s BuildUp method to inject the dependency into the existing object.

Setting up the HttpApplication

The application object stores the container and implements an interface that the InjectorModule can access the container through.

public interface IHttpUnityApplication
{
    IUnityContainer UnityContainer { get; } 
}

And the Application class in the global.asax.cs file looks like this:

public class MvcApplication : System.Web.HttpApplication, IHttpUnityApplication
{
    // This is static because it is normal for ASP.NET to create
    // several HttpApplication objects (pooling) but only the first
    // will run Application_Start(), which is where this is set.
    private static IUnityContainer _unityContainer;

    protected void Application_Start()
    {
        _unityContainer = UnityBootstrapper.Initialise();
	// Do other initialisation stuff here
    }

    // This implements the IHttpUnityApplication interface
    public IUnityContainer UnityContainer
    {
        get { return _unityContainer; }
    }
}

The UnityBootstrapper initialises the container for MVC, it is created by the Unity.Mvc4 NuGet package (there’s also a Unity.Mvc3 package too). You can read more about it here.

The InjectorModule

Next up the InjectorModule is created

public class InjectorModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        // Get the IoC container from the application class through
        // the common interace.
        var app = (IHttpUnityApplication) context;
        IUnityContainer container = app.UnityContainer;

        // Wire up each module that is registered with the IoC container
        foreach (var module in context.GetRegisteredModules(container))
            container.BuildUp(module.GetType(), module);
    }

    public void Dispose()
    {
    }
}

I’ve also been a wee bit sneaky and created an extension method on HttpApplication to work out which are the registered modules so that the code above is a bit nicer. That code is:

public static class HttpApplicationExtensions
{
    public static IEnumerable GetRegisteredModules(this HttpApplication context, IUnityContainer container)
    {
        var allModules = context.Modules.AllKeys.Select(k => context.Modules[k]);
        var registeredModules = allModules.Where(m => container.IsRegistered(m.GetType()));
        return registeredModules;
    }
}

Wiring it all up

The container must be told which modules have dependencies to inject and what properties to set. e.g.

container.RegisterType<MyCustomModule>(
    new InjectionProperty("TheDependentProperty"));

MyCustomModule is the class that implements the IHttpModule interface, and you need to supply an InjectionProperty for each of the properties through which the IoC containers will inject a dependency.

You can also decorate the properies with the [Dependency] attribute, but then you are just wiring in a dependency on the IoC container itself… which is not good.

Finally, this new module has to be wired up in the web.config file

  <system.webServer>
    <modules>
      <add name="InjectorModule"
           type="Web.IoC.Unity.InjectorModule" />
      <!-- Other modules go here, after the Injector Module -->
    </modules>

By putting the Injector module ahead of other modules in the web.config it means it gets a chance to run and inject the depedencies into other modules that have yet to be initialised.

Other considerations

The IHttpModule interface defines a method, Init(), that takes an HttpApplication as a parameter. Naturally, that’s difficult to mock out in a unit test.

What I did was to extract all the bits that I needed in the Init() method and pass them to another method to do the work. For example, HttpContext is easy to do because ASP.NET MVC provides an HttpContextWrapper and the method that is doing all the work just takes an HttpContextBase, which is easily mocked in a unit test.

public void Init(HttpApplication context)
{
   var wrapper = new HttpContextWrapper(context.Context);
   InitImpl(wrapper);
}
public void InitImpl(HttpContextBase httpContext)
{
    // Do stuff with the HttpContext via the abstract base class
}

Tip of the Day: Make Outlook 2013 display the Weather in Celsius

At work we’re upgrading to Outlook 2013. One of the new features is that the Calendar will display the weather for the next few days.

Outlook 2013 Displaying the Weather in Fahrenheit

If you like this, that’s great. However, most of the world uses Celcius, but out of the box Outlook displays Fahrenheit (regardless of the locale set up on your machine). In fact, it also defaults to New York as the city.

Changing the Weather Location

It is easy enough to change the weather location. Just click on the name of the city and you get a drop down box.

Weather Location Drop Down Box

If the city you want is not in the list, just select “Add Location” and you get a search box to type in the city that you want.

Search for Weather Location

Change the Temperature Scale to Celsius

Changing the temperature scale to Celsius is a little bit more involved. First click the “File” menu in the top right corner of the window.

File Menu Button in Outlook 2013

Then select the “Options” button from the new menu.

File Menu Details

This will display the options dialog. First, click the “Calendar” button in the left menu. Then scroll down to the bottom of the options that are presented. The Weather options are last. You’ll see you can then select the temperature scale (“Celsius” or “Fahrenheit”) that you want. Or you can even turn off the weather too.

Options Dialog

Then you can just “OK” the dialog and the weather will be updated into Celsius. Much more civilised.

Much more civilised, the temperature in Celsius

 

 

Tip of the Day: Getting TFS to remember you each time you open Visual Studio

Because the TFS Server where I work is not on the domain, it will prompt you for credentials each time you log in (unless you’ve previously used the web access and checked the “Remember Me” option). If you don’t want to use the web access portal, you can still get TFS to remember your credentials and not ask you each time you log in.

Go in to the control panel and select “User Accounts”

In the next screen click “Manage Windows Credentials”

In the next screen click “Add Windows Credential”

Then type your details into the form, and press “OK”

You’ll see your new set of credentials appear in the Credential Manager page:

Now when you open up Visual Studio it won’t prompt you for your credentials all the time.

Tip of the day: How to tell why your app couldn’t log on to SQL Server

When you get a log in failure on SQL Server the message you get back from SQL Server Management Studio, or in a .NET Exception is vague for security. They don’t want to give away too much information just in case.

For example, the exception message will be something like “Login failed for user ‘someUser’.” which doesn’t give you much of a clue as to what is actually happening. There could be a multitude of reasons that login failed.

If you want more information about why a log-in failed you can open up the event viewer on the machine that SQL Server is installed on and have a look. You’ll find a more detailed message there.

The wider messages may be things like:

  • “Login failed for user ‘someUser’. Reason: Could not find a login matching the name provided. [CLIENT: <local machine>]”
  • Login failed for user ‘someUser’. Reason: Password did not match that for the login provided. [CLIENT: <local machine>]
  • Login failed for user ‘someUser’. Reason: Failed to open the explicitly specified database. [CLIENT: <local machine>]
    Note: This could be because the database doesn’t exist, or because the user doesn’t have permissions to the database.
Follow

Get every new post delivered to your Inbox.