I've found a bug with IE8 Beta 2 (in both IE7 and IE8 browser modes) where list boxes that, although disabled but containing selected items, do not show the selected items. Here is an example of what should be displayed

For those of you who are not using IE8 Beta 2, here is what it appears like:

I have logged the bug on their forums at http://www.microsoft.com/communities/newsgroups/list/en-us/default.aspx?dg=microsoft.public.internetexplorer.beta&tid=55a9ace5-380d-408c-aa54-2d997de1f245&cat=〈&cr=&sloc=&p=1 so read and vote if you've found this to be a problem too!


Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist

One of IE8's new features is a that when closing a window or tab, it can remember the session ID and therefore maintain the session with a website. This is an advantage if you accidentally close a window or tab, but there is a problem.

For example, if you have several logins for a site, each login giving totally separate functionality of the site (e.g customer and administrator), then you may close your browser and login as someone else. What you may find is that when you open a new window, you are already logged in as the other person. Why does this happen?

IE8 seems to use the first window a storage mechanism for sites visited in this browsing session. When visiting a site, the unique Session ID is generated and then stored in this host process. When opening new tabs and windows the new process checks the host process to see if the website has been visited and if so returns the existing session ID.

So to re-iterate, if you have at least 1 browser window open, all subsequent tabs and windows pointing to a specific site will all generate the same session ID.

In order to get around this "problem", you should close all instances of IE8. The session information seems to be stored in memory rather than on disk, so by closing all of these instances, the problem goes away.

This serves as a warning to both developers and kiosk/Internet café users. Developers should provide the ability to log out of a site so that the Session is cleaned up after a user logs out. Kiosk/Internet Café users should close ALL Internet browser sessions down before leaving!


Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist

The 3 types of connections Silverlight can make are:

  • Connections to web services and WCF services
  • HTTP requests (via HttpWebRequest and WebClient)
  • Raw data transfers

When building one of your early applications, you may choose to try out one of these classes to get back a really simple piece of HTML, purely to test the connection. For example:

protected void Button_Click(object sender, EventArgs e)
{
    WebClient wc = new WebClient("http://www.google.com");    
    wc.DownloadStringAsyncCompleted += new EventHandler<DownloadStringEventArgs>(wc_DownloadStringCompleted);    
    wc.DownloadStringAsync();
}

protected void wc_DownloadStringCompleted(object sender, DownloadStringEventArgs e)
{
    if(e.Error == null && e.Cancelled == false)  
    {        
        Debug.WriteLine("Data downloaded = " + e.Result);    
    }
}

(N.B I apologise if this doesn't compile, I've just typed this by hand.)

If you run this, you'll find it generates a SecurityException, but why?

To improve security, the only connections you can make without any security implications is your own website. If you want to call another website, Silverlight needs to check a few things. Firstly, it looks for a policy file called "clientaccesspolicy.xml", which is a file used by Adobe Flash to find out if it allows connections from Flash applications. If this file is missing, it then looks for "crossdomain.xml", which is a Silverlight version of this file.

  • If one of these exists AND the policy file allows connections, then the application will be allowed to connect.
  • If neither exists, or the policy in an existing file denies access to the requested virtual directory, then a SecurityException will be thrown by the application.

To overcome this problem, you have 2 options

  1. Check the website has an API to use the capabilities you are after. Google and Digg have service APIs in order to allow applications to do this.
  2. Write a web service (or WCF service), that does the enquiry for you.

If you need to see the contents of these files, I have found Fiddler an excellent tool for this purpose.


Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist

I put my VPC's on my external hard disk and run them off there, as the hard drive can run independently of Windows.

I've noticed over the past few months, that randomly, my external USB 2.0 hard drive (Freecom 400GB) disconnects for no reason and I get a balloon in the system tray with the title "Delayed Write Problem" , then something to do with G:\$MFT or G:\$Bitmap.

Yesterday, I was defragmenting my external hard disk and noticed it kept happening. I turned it off and on again, started defragmenting and the same problem happened.

I thought it might be the writing caching, which helps improve performance, so when viewing the properties of the drive (My Computer -> [External Hard Disk] -> Right-click Properties -> Hardware -> Properties -> "Enable write caching on the disk"), I turned this option off.

Another defragmentation session and the same problem happened again and again.

What I finally realised was that I was using some software (DAEMON Tools Lite) for mounting ISO's to a CD drive. Although the software wasn't running, I still had the CD drive present in my drive listing. I loaded up DAEMON Tools Lite and turned off the emulated CD drive (which I wasn't using anyway) and HEY PRESTO! it was working.

I defragmented half the drive and then turned write caching back on and it was fine!

Hope this helps someone, as when a hard drive disconnects and a VPC is running off it, you are in trouble!


Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist

After various conversations on both internal and external projects, I’ve noticed that some of our web projects were being developed using a Session state called InProc.

InProc means In-Process, so IIS is hosting all of the

Session[“Dom”] = “Idiot!”; 

variables. Now, if the web application eats up too much memory, IIS 6 and above can be configured to recycle the Application pool – a contained unit of web sites, in order to free up memory. This is good for IIS but baaaad news for your website, as everything in the Session is lost – that could be shopping basket, current order status, user details! InProc is a bit of a quick and nasty method of developing as it just does its job, assuming that you are not going to host this to a larger audience (over about 5 users).

As I found out with any large project, nothing goes to plan, so, the best thing to do is to use StateServer and not InProc – but WHY?

StateServer is a totally out-of-process service that runs on either the same web server or a different server entirely. Session data is saved to this service so if the AppPool recycles, you have no problems whatsoever. Also, the data needs to serialize properly in order for it to be saved to the service.

Whats the point I hear you ask? Well, the point is that if you use InProc and your application gets load balanced (often without your knowledge), the website won’t work properly. Remember, load balancing is decided, by either the hardware or the software, to help manage the network traffic to a destination server. So 1 request to go to Server1 and another or Server2, or even ServerX! Youch! So your site’s Session could be stored on another machine.

StateServer works because all of the web.config’s point to the same machine, so they all work off that one service.

The other option is SQLServer, which stores it in SQL Server, which is more for web farms (multiple physical PCs), rather than web gardens (multiple virtualized PCs). Or you can use Custom for a custom implementation (e.g ODBC or XML), or Off to turn it off completely.

Therefore, a good recommendation is to always change your web.config to say:

<sessionState mode=”StateServer” … />

And start the ASP.NET State Service on your machine. This way to can always revert to InProc if you need to, but you are still ready for the switch over.

Believe me, it’s a lot easier to start out this way, rather than have to work backwards.

It is always a worthwhile exercise!


Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist

When working on a project recently, the data saved back to the database was huge. We are talking well over 100 properties. After talking to my Java buddy, he said that one way is to create an IsDirty method that returns if the object has changed state.

The IsDirty() method is used to query the state of an object - if it has been modified or not. The implementation is up to the developer, but ultimately it's use can save you a trip to the data source.

I have split this example into 3 stages:

  1. First attempt
  2. Refactored
  3. Event Handled

N.B. This article helps someone in (archaic) .NET 2.0 - but if you've looking to develop for .NET 3.5, it might be worth looking into DependencyProperty's, which caters for this sort of problem.

First Attempt

The problem I found when prototyping this is that it can be quite impractical at first glance:

class Customer
{
    private string firstName, surname;
    public Customer(string firstName, string surname)
    {
        this.firstName = firstName;
        this.surname = surname;
    }

    public string FirstName
    {
        get { return firstName; }
        set 
        { 
            if( firstName != value )
            {
                IsDirty = true;
                firstName = value;
            }
        }
    }
    public string Surname
    {
        get { return surname; }
        set 
        { 
            if( surname != value )
            {
                IsDirty = true;
                surname = value;
            }
        }
    }

    public bool IsDirty { get; private set; }
}

 

This is a bit bloated. Also, it relies on every property having to check for itself whether it is equal or not, setting the IsDirty property and also assigning the value.

After writing this and implementing a few more properties I found this to be a bit too impractical. Instead, I realised that they are all basically doing 3 steps:

  1. Checking the previous value to the new value.
  2. Setting IsDirty.
  3. Assigning the new value.

This example needs simplifying - or refactoring to be more precise.

Refactoring

Instead, I decided to implement this behaviour in a method called SetValue<T>() , which would raise events when a property has changed. This allows the IsDirty property to be changed centrally and debugging to be centralized.

Firsty I created the method:

private void SetValue<T>(ref T varName, T value)
{
    if (varName.Equals(value))
        return;
    
    IsDirty = true;
    varName = value;
}

 

Now, we can change our properties to:

public string FirstName
{
    get {return firstName; }
    set
    {
        SetValue<string>(ref firstName,value);
    }
}

public string Surname
{
    get {return surname; }
    set
    {
        SetValue<string>(ref surname,value);
    }
}

This is one implementation of it, but I decided to extend it to event handling as well, so that even the outside world can be notified about what is changing.

Event Handling

I decided to also implement this is in a typical Microsoft fashion: OnPropertyChanging and OnPropertyChanged.

In order to turn this into an event driven model I need to do a few things:

  1. Create some event arguments describing what is being changed.
  2. Add some event handlers to trigger a notification that they have been changed.
  3. Trigger the events from within your code
  4. (Optionally) wire up the events.
  5. Trigger the events from within your code

Create event arguments

Since I am using events, I want to create event arguments detailing what has changed. I have implemented this in 2 identical classes (and 1 base class). Here I have implemented a base class, and 2 classes which improve the clarity of the base class. I have chosen clarity over code bloat:

//Base class implementation
public abstract class PropertyChangeEventArgs : EventArgs
{
    public string PropertyName { get; protected set; }
    protected object Value { get; set; }

    public PropertyChangeEventArgs(string propertyName, object before)
    {
        this.PropertyName = propertyName;
        this.Value = before;
    }
}

//Holds arguments before the proerty has changed
public class PropertyChangingEventArgs : PropertyChangeEventArgs
{
    public object ValueBeforeChange
    {
        get
        {
            return this.Value;
        }
    }

    public PropertyChangingEventArgs(string propertyName, object before) 
        : base(propertyName,before)
    {
    }
}

//Holds arguments after the proerty has changed
public class PropertyChangedEventArgs : PropertyChangeEventArgs
{
    public object ValueAfterChange
    { 
        get 
        { 
            return this.Value; 
        } 
    }

    public PropertyChangedEventArgs(string propertyName, object after) 
        : base(propertyName, after)
    {
    }
}

Create event handlers

Now implement some event handlers:

public event PropertyChangingEventHandler PropertyChanging;
public delegate void PropertyChangingEventHandler(object o, PropertyChangingEventArgs e);

public event PropertyChangedEventHandler PropertyChanged;
public delegate void PropertyChangedEventHandler(object o,PropertyChangedEventArgs e);

Trigger the events from within your code

Now I need to trigger these events from the SetValue<T>() method. I will also need to find out what property was called by this SetValue<T>() method.

private void SetValue<T>(T varName, T value)
{
       if (varName.Equals(value))
           return;

       //TODO: Find the property's name that is calling this method
       string propertyName = "MyProperty";

       if (PropertyChanging != null)
           OnPropertyChanging(this, new PropertyChangingEventArgs(propertyName, varName));

       varName = value;

       if (PropertyChanged != null)
           OnPropertyChanged(this, new PropertyChangedEventArgs(propertyName, varName));
   }

The last thing to do is to find the property that is calling this method. This can be done using Reflection, by looking up the call stack. By getting the previous "frame", we can deduce where this is being called from. In our case, this is called "set_FirstName". Remove the "set_" and we have our property name:

StackTrace st = new StackTrace();
StackFrame current = st.GetFrame(1);
string propertyName = current.GetMethod().Name.Replace("set_", "");

(Optionally) wire up the events

I want to subscribe to the OnPropertyChanged event, so that I can set the IsDirty property within it. I have done this within a private constructor:

private Customer()
{
   PropertyChanged += new PropertyChangedEventHandler(OnPropertyChanged);
}

public Customer(string firstName, string surname) : this()
{
   this.firstName = firstName;
   this.surname = surname;
}

(Optionally) trigger the events from within your code

Now, I want to move the IsDirty assignment out of the SetValue() method because although overkill, it is not related to the setting of the value. It is related to the event but not the assignment. It also means that you have just wasted 15 minutes reading this article! :-) :

private void OnPropertyChanged(object sender, PropertyChangedEventArgs ea)
{
   IsDirty = true;
}

Summary

So what have we done? We've looked at ways in which we can implement notification within a class, so that we can save a database access. When getting to a large number of properties, we can bypass each save and also allow the outside world to be notified of its changes.

In the first example,we saw a cheap and nasty way of doing it, but impractical for larger classes. In the second example we saw a better implementation and in the third example we added event handling to extend the functionality further.

I hope this article helps someone - but if you've looking to develop for .NET 3.5, it might be worth looking into DependencyProperty's, which caters for this sort of problem.

Here is the full source code to have a play with:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Customer c = new Customer("Dominic", "Zukiewicz");
            c.FirstName = "Dommy dom dom";

            Console.WriteLine("Customer.IsDirty = " + c.IsDirty);

            Customer c2 = new Customer("Dominic", "Zukiewicz");
            c.Surname = "Zukiewicz";

            Console.WriteLine("Customer2.IsDirty = " + c2.IsDirty);
        }
    }

    class Customer
    {
        private string firstName;
        private string surname;

        private Customer()
        {
            PropertyChanged += new PropertyChangedEventHandler(OnPropertyChanged);
        }

        public Customer(string firstName, string surname) : this()
        {
            this.firstName = firstName;
            this.surname = surname;
        }

        public string FirstName
        {
            get
            {
                return firstName;
            }
            set
            {
                SetValue(ref firstName, value);
            }
        }

        public string Surname
        {
            get 
            { 
                return surname; 
            }
            set
            {
                SetValue(ref surname,value);
            }
        }

        public bool IsDirty { get; private set; }


        private void SetValue(T varName, T value)
        {
            if (varName.Equals(value))
                return;

            StackTrace st = new StackTrace();
            StackFrame current = st.GetFrame(1);
            string propertyName = current.GetMethod().Name.Replace("set_", "");

            if (PropertyChanging != null)
                OnPropertyChanging(this, new PropertyChangingEventArgs(propertyName, varName));

            varName = value;

            if (PropertyChanged != null)
                OnPropertyChanged(this, new PropertyChangedEventArgs(propertyName, varName));
        }

        public event PropertyChangingEventHandler PropertyChanging;
        public delegate void PropertyChangingEventHandler(object o, PropertyChangingEventArgs e);

        public event PropertyChangedEventHandler PropertyChanged;
        public delegate void PropertyChangedEventHandler(object o,PropertyChangedEventArgs e);

        private void OnPropertyChanged(object sender, PropertyChangedEventArgs ea)
        {
            Debug.Print("Property: {0}, After: {1}", ea.PropertyName, ea.ValueAfterChange);
            IsDirty = true;
        }

        private void OnPropertyChanging(object sender, PropertyChangingEventArgs ea)
        {
            Debug.Print("Property: {0}, Before: {1}", ea.PropertyName, ea.ValueBeforeChange);
        }
        
    }

    //Base class implementation
    public abstract class PropertyChangeEventArgs : EventArgs
    {
        public string PropertyName { get; protected set; }
        protected object Value { get; set; }

        public PropertyChangeEventArgs(string propertyName, object before)
        {
            this.PropertyName = propertyName;
            this.Value = before;
        }
    }

    //Holds arguments before the proerty has changed
    public class PropertyChangingEventArgs : PropertyChangeEventArgs
    {
        public object ValueBeforeChange
        {
            get
            {
                return this.Value;
            }
        }

        public PropertyChangingEventArgs(string propertyName, object before) 
            : base(propertyName,before)
        {
        }
    }

    //Holds arguments after the proerty has changed
    public class PropertyChangedEventArgs : PropertyChangeEventArgs
    {
        public object ValueAfterChange
        { 
            get 
            { 
                return this.Value; 
            } 
        }

        public PropertyChangedEventArgs(string propertyName, object after) 
            : base(propertyName, after)
        {
        }
    }
}

Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist

When writing stored procedures or views, I always create them in Visual Studio (2005/2008) and then run them on a specified database. When using "SELECT *", it is compact, but obviously does not help you find the columns of the table or view.

When using the IDE, I added a new SQL Script for Stored Procedures, and then I typed:

SELECT *
FROM Customers

and a blue box surrounded the statement. I right-clicked -> Design SQL Block.

The designer then listed all of the column names for me, and when clicking OK, instantly put them back into the SQL script I was creating!

SELECT  CustomerID, CompanyName, ContactName, ContactTitle, 
Address, City, Region, PostalCode, Country, Phone, Fax
FROM Customers

For the table I was using, this list over 60 columns for me!

So if you want a quick way of listing all of the column names for table of view:

  1. Add a database project to your site (if you haven't already done so)
  2. Right click Queries -> Add SQL Script
  3. Choose Stored Procedure Script
  4. Type your SELECT * From XYZ statement
  5. Right click -> Design SQL Block
  6. Click OK.

The designer will be updated with the new query.


Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist

I was trying to parse a file which was divided into numerous parts - each one 12 lines long. For debugging, I was interested in how fast the file was being read and processed and therefore looked at the StreamReader.BaseStream.Position property. Here is an example of what I was trying to do:

class Program
{
static void Main(string[] args)
{
string filename = @"C:\windows\windowsupdate.log";
string filenameBackup = filename + ".bac";
File.Copy(filename, filenameBackup);

FileStream fs = new FileStream(filenameBackup, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fs);

int lineNumber = 0;

while (!sr.EndOfStream)
{
Console.WriteLine("Lines Read = {0}, Position = {1}", lineNumber, sr.BaseStream.Position);
string[] lines = ReadXLines(sr,5);
lineNumber += lines.Length;
}

Console.Read();
}

private static string[] ReadXLines(StreamReader sr, int linesToRead)
{
string[] lines = new string[linesToRead];

for (int lineNumber = 0; lineNumber < lines.Length; lineNumber++)
{
lines[lineNumber] = sr.ReadLine();
}

return lines;
}
}

Now, the output on my computer was this:

Lines Read = 0, Position = 1024
Lines Read = 5, Position = 1024
Lines Read = 10, Position = 1024
Lines Read = 15, Position = 2048
Lines Read = 20, Position = 2048
Lines Read = 25, Position = 3072
Lines Read = 30, Position = 3072
Lines Read = 35, Position = 4096
Lines Read = 40, Position = 5120
Lines Read = 45, Position = 5120
Lines Read = 50, Position = 6144
Lines Read = 55, Position = 7168
Lines Read = 60, Position = 7168
Lines Read = 65, Position = 8192
Lines Read = 70, Position = 8192
Lines Read = 75, Position = 9216
Lines Read = 80, Position = 9216
Lines Read = 85, Position = 10240
Lines Read = 90, Position = 10240
Lines Read = 95, Position = 11264
Lines Read = 100, Position = 11264
Lines Read = 105, Position = 12288
......

What is odd about this sequence is that the position of the FileStream is already at 1024 before anything has been read! Also, the 1024 position stays the same for 2 reads. Why is this?

The StreamReader class is a buffered reader. Therefore, it is reading the stream before anything is processed and when reading directly from StreamReader, if the amount read does not extract the entire buffer, then the position of the underlying stream doesn't change.

Unfortunately, there is nothing you can do about this. Therefore the only 2 ways you can keep track of the position is to:

  • Count how many characters are in each line (plus the Environment.Newline) and total up the position line by line.
  • Create your own implementation of the FileStream, which has a ReadLine() method. This method should continue to read the Stream until Environment.Newline is encountered. Remember, Environment.Newline is not included in the string returned.

Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist

WPF is revolutionary as it re-invents the Windows design and programming for the Microsoft platform. But why bother?

I could write an article for hours and hours on the changes brought about with WPF. Here, I will give a very brief overview of the more visual changes brought about.

History

If you have had any experience programming Windows in .NET, VB6 or C++ MFC, you'll have heard of GDI. GDI (more recently GDI+) is an API which you use to render text images and other custom drawing functions (like lines, circles, rectangles etc). The GDI library has been around since Windows 95 and was a huge hit with developers for drawing basic elements on the page. The standard Windows forms and controls are rendered by the User.dll (more recently User32.dll).

The problem that faces GDI in the modern computer is that it is implemented in software. In 1995, this is a sensible solution, but in 2008 the average computer has a half decent graphics processor. Also, DirectX has matured a huge amount since Windows 95 and this isn't utilised at all. We need a way of using the hardware to do our UI rendering so that we can draw both 2D and 3D objects within our applications, without imposing too much on the software core of the OS.

Overview

Graphics

WPF replaces the slow GDI libraries by using DirectX as its UI drawing library. WPF is also intelligent enough to know about your hardware capabilities, falling back to the slower software rendering should it need to. WPF's DirectX rendering capabilities only work for Windows XP and Windows Vista and even then there is a catch. When Microsoft were thinking about Vista and "Indigo" (code name for the WPF project), they released a new specification for hardware manufacturers to follow, to accommodate the new interface. Therefore, if your video card didn't receive a patch after 2004, OR they haven't added this requirement, then you will only have software rendering capabilities.

That doesn't mean that Direct3D and OpenGL are defunct. WPF is an implementation and is not as fast as Direct3D. If you need to create some real-time, high resolution graphics package or game then WPF will not be the way to go. WPF does cater for 3D graphics, rotation, lighting, transformation etc, but it does not replace the abilities of the Direct3D.

Flexible UI components

Some of the web concepts have really given WPF so great ideas on how to improve the framework. These include:

  • Layouts are flexible to the width of the application.
  • Creating text documents similar to Microsoft Word are as simple as adding headings, paragraphs, tables with captions, images etc.
  • Create styles for controls and apply them across your application - much like skins in ASP.NET.
  • Data binding can be done at page level, rather than by each control separately.

Think about a list. A list, as a high level abstract is just a grouping of 1 or more items. That's it. Therefore, the current ListBox implementation is quite inflexible; you just have a bit of text for the description. If you work harder you could get an image in there as well, but ultimately, the ListBox is really a TextListBox.

An awesome example of the thinking behind WPF is that the ListBox has been totally redesigned to hold just about anything you want. If you want an image/text combination, you group the 2 together and add it to the list! Easy peesy. You might be surprised that a CheckBoxList doesn't exist - why? Because it is just a list of CheckBox controls - so why create a new control, when a ListBox with CheckBoxes in does the same thing!

Resolution Independence

When working off high resolution monitors, the pixel density is a lot higher. This means if 2 screens of the same size, but with different resolutions, display the same size window, the higher resolution monitor will show the window to be much smaller. I personally use a high resolution laptop, therefore my task bar is tiny. You can increase the size of your desktop by either:

  • Changing the font sizes
  • Changing the DPI settings (preferred)

By changing your DPI settings, the fonts remain proportionate to your screen.

The only problem is that applications built prior to XP didn't have to take this into account and therefore changing the DPI can make some windows look a little strange, whereas others (which have catered for it) remain relatively normal. In Vista, it uses a slightly different technology called bitmap scaling which intelligently stretches images and fonts to fill out the DPI setting.

Event Model Changes

The event notification model has changed as well, meaning that events can "bubble" up to parent containers if needs be.

Navigation support

Users are getting more and more familiar with the navigation of web pages - a step by step approach to using sites. The WPF team have created page based navigation too, with page history. This allows users to create a similar navigation system to that of web pages, but from a user interface.

Summary

There are many many many more exciting features that WPF brings to .NET, and you will find huge books on the subject. Hopefully, I have given a small taster of the high level features available to you and in the future, I will try and provide some samples of what it can do.


Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist

Microsoft recently (on my birthday) released a tool to analyse coding structure and formatting. No - its not FxCop - StyleCop analyses syntactical formatting. Let me explain:

Background

When Microsoft released FxCop, some people cringed. I remember at my previous job when having a code review and the conversation following:

  • Consultant: "Have you FxCop'd it?".
  • Me: "No...."
  • Consultant: "Hahahah - see you in 3 months!"

Those days, for me anyway, have gone. I started to use it in my everyday coding and am now pleased I use it without a second thought.

In my position with this company, I have tried to promote its use and benefits, because it promotes good coding guidelines standard approaches to software development.

FxCop works by analysing compiled code and therefore can look into its improvements at a detailed view. This is all good, but what about coding standards for syntax!?

Overview

StyleCop is a tool written and used by Microsoft to ensure all of their code is formatted, commented and laid out in a fixed format. It has quite a rigid structure to it, but so it should. I've read lots of threads about people complaining about its flexibility, but that's the whole point of standards - they don't change (often) .

Before I provide a link, I just want to show you how much you need to do, in order to pass one of these successfully. Here is a typical piece of code:

using System;
using System.Diagnostics;
using LogicAndData;

class User {

private string _username;

public string Username
{
get { return _username; }
}

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string _password;

public bool IsCorrectPassword(string guess)
{
if (String.IsNullOrEmpty(guess))
return false;

return guess.Equals(_password, StringComparison.CurrentCulture);
}

public User(string username, string password)
{
if (username == null)
throw new ArgumentNullException(Resources.Username_ParameterName);
else if (username.Length == 0)
throw new ArgumentException(Resources.Username_ParameterEmpty, Resources.Username_ParameterName);

if (password == null)
throw new ArgumentNullException(Resources.Password_ParameterName);
else if (password.Length == 0)
throw new ArgumentException(Resources.Password_ParameterEmpty, Resources.Password_ParameterName);

_username = username;
_password = password;
}
}

Pretty standard stuff really. Okay, its missing comments but it does pass FxCop! So lets have a look at the errors generated for this class:

styleCopErrors

So, what are the problems?

  1. SA1101: If you are referring to member variables (variables at class level), then you should use the keyword "this." to be explicit (2 errors)
  2. SA1201: This is a formatting issue - the order is - private fields, constructors, properties, public methods, private methods. (2 errors)
  3. SA1309: Don't use underscores! The "this" keyword implies it. (2 errors)
  4. SA1400: Class must have an identifier instead of the default (protected internal) (1 error)
  5. SA1503: If statements must use { }, even if they are only 1 line of code (6 errors)
  6. SA1600: All classes, interfaces, methods, properties and fields (optional) MUST have an XML header for documentation purposes. (4 errors)
  7. SA1633: Related to the above, there is a preset format for the documentation for the header of the file that MUST be at the top of each file created. (1 error)

Using StyleCop

What does this improve? relating to the above:

  1. It is clearer what you are working with. You don't need to use prefixes, as by using "this" you are describing which one you are referencing anyway.
  2. This just standardises the layout of your code.
  3. For clarity. It doesn't like Hungarian notation either, but DOES allow you to add acceptable notations should you wish.
  4. Be explicit about the access type, as you may not understand the access of an unmarked class.
  5. By laying out if statements this way, you are totally consistent across your code.
  6. Documentation - who doesn't document their code!?
  7. Add a header to just clarify what's doing on, any copyright notices, authors etc.

So lets see what this looks like without any errors at all!

[40 minutes later and 3 cups of coffee].... only joking - it probably took 5 minutes, mainly because I have used it before:

// <copyright file="User.cs" company="Interakting">
//     Copyright (C) 2008 Interakting. All rights reserved
// </copyright>
// <author>Dominic Zukiewicz</author>
using System;
using System.Diagnostics;
using LogicAndData;

/// <summary>
/// The User class describes a single username/password combination. The password
/// is kept secret, but timescales limit security.
/// </summary>
internal class User
{
    /// <summary>    
    /// The username of the user.    
    /// </summary>    
    private string username;

    /// <summary>    
    /// The password of the user.    
    /// </summary>    
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private string password;

    /// <summary>    
    /// Creates a user with a specific username/password combination    
    /// </summary>    
    /// <param name="username">The username of the user.</param>    
    /// <param name="password">The password of the user.</param>    
    public User(string username, string password)
    {
        if (username == null)
        {
            throw new ArgumentNullException(Resources.Username_ParameterName);
        }
        else if (username.Length == 0) 
        { 
            throw new ArgumentException(Resources.Username_ParameterEmpty, Resources.Username_ParameterName); 
        } 
        
        if (password == null) 
        {
            throw new ArgumentNullException(Resources.Password_ParameterName); 
        } 
        else if (password.Length == 0)
        { 
            throw new ArgumentException(Resources.Password_ParameterEmpty, Resources.Password_ParameterName); 
        }
        
        this.username = username; 
        this.password = password;
    }

    /// <summary>    
    /// Gets the username of the user.    
    /// </summary>    
    public string Username 
    { 
        get 
        { 
            return this.username; 
        } 
    }
    
    /// <summary>    
    /// Checks to see if the password of the user matches that of the stored password.    
    /// </summary>    
    /// <param name="guess">The guess for the password.</param>    
    /// <returns><code>true</code> if it matches, else <code>false</code>.</returns>    
    public bool CheckPassword(string guess)
    {
        if (String.IsNullOrEmpty(guess))
        { 
            return false; 
        }
        
        return guess.Equals(this.password, StringComparison.CurrentCulture);
    }
}

So what's changed - really?

What I have noticed, is that there is a good separation of the code, a very clear layout structure and of course, forcing you to comment your methods, which I really like. You'll find that the code is clearer because of the white-space implied by the curly brackets.

It can seem quite daunting to see all of these errors, but like FxCop, once you start to take these rules onboard, you are more likely to code in this style rather than turn away from it.

Here is the link to Microsoft's StyleCop: http://code.msdn.microsoft.com/sourceanalysis/Release/ProjectReleases.aspx?ReleaseId=1047


Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist