logo
  • Jobs
  • About Me
  • Contact
  • Home

Archive for January, 2006

« Previous Entries

Developing portable ASP.NET apps

We develop ASP.NET applications in our environment that may or may not be run on a clustered environment. As part of this clustered environment, we have session state set to SqlServer in the web.config file.

Due to this, we always have to be really careful to make sure that any items we add to the Session collection either has the [Serializable] attribute or implements ISerializable.

It seems as though, without fail, an object generally tends to be forgotten. I’ve found a quick way to make sure that this doesnt happen.

One of the first things Ive started doing with any new application I develop is to change the session state to use StateServer. Prior to doing this, you need to insure that you’ve started the ASP.NET State Server service using the Services MMC, or issuing the command ‘net start aspnet_state’ on the command line. This allows the Session to go through the same process and quickly exposes any serialization requirements you may have missed.

Once you deploy your application, you can always set it back to InProc, or change it to SqlServer, but you now know that your application will work correctly with either setting.

1 Comment

iPod Nano

Several months ago, I bought myself an iPod Nano. This was the first mp3 device Id ever purchased and so far, I absolutely love this thing. Except for one thing.

I have a playlist of songs that I listen to when Im at the gym running. Its boring when the songs play in the same order every day at the gym, so I would really *love* to have a feature that lets me shuffle the songs on an individual playlist.

I know that I can set up playlist shuffling at the master level, however, this ends up pissing me off, because then some other playlists end up playing out of order. Of course, there is the possibility that this feature is hidden elsewhere on the device, so if you know how to do this, Id love to know.

If this capability is not there, Ill make a request to Apple to please add this to an iPod update.

4 Comments

A few more live templates

A few weeks ago, I talked about TDD bliss and showed some live templates that I had created for Resharper to relieve some of the more mundane parts of writing unit tests.

The original version of the templates included only a Test method and a TestFixture class. I’ve updated the live template file to now also include these templates:

  • te : A test with an ExpectedException attribute.
  • ti : A method called TestInitialize decorated with the [SetUp] attribute.
  • td : A method called TestCleanup decorated with the [TearDown] attribute.

This should handle most scenarios you encounter while using NUnit. Of course, these templates can easily be modified to support the VSTS Unit Testing Framework.

Download now (zip | xml)

1 Comment

Refactoring: Explained

Yesterday, at work, we had a very lively discussion about refactoring. I took a few things away from that discussion and thought I would address these in this particular entry.

First, I believe there is a fundamental misunderstanding of the definition of refactoring. Refactoring, as defined by Martin Fowler in his book is “a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior”. Refactoring can be used as both a verb and as a noun. When used as a noun, refactoring is a small behavior preserving transformation. Grouping several of these transformations defines the verb of refactoring.

That said, by looking again at the definition, it is important to realize that you do not “refactor” a UI, in the same way that you do not “refactor” a word document. The key part of the definition is “altering its internal structure without changing its external behavior”. When you work with UI changes, you are redesigning an interface, not refactoring it.

Another point that I took away from our discussion was the lack of understanding how small a refactoring actually is. Its important to note that coming to a loosely coupled, highly cohesive solution is the result of an iterative process of going through these very small transformations, which will lead you to the ultimate goal.

The key blocker to getting legacy code under test is breaking dependencies, so lets look at how we can accomplish this with a small series of refactorings. Let’s say we have a simple class that uses HttpSessionState extensively. Our goal is to get this class under test.

The legacy code that we are looking at is defined like this:

public class MyPage
{
    public void Method1()
    {
        HttpContext.Current.Session["key"] = "value1";
    }
 
    public void Method2()
    {
        string s = HttpContext.Current.Session["key2"];
        // do something with s
    }
 
    public void Method3()
    {
        string s = HttpContext.Current.Session["key"];
        // do something with s
    }
}

We can see here that we have a little bit of code duplication. It may not be completely obvious where the duplication lies right now. However, after applying one simple refactoring, called ExtractMethod, to this code we can see how we’ve eliminated duplication.

public class MyPage
{
    public void Method1()
    {
        AddToSession("key", "value1");
    }
 
    public void Method2()
    {
        string s = RetrieveFromSession("key2");
        // do something with s    
    }
 
    public void Method3()
    {
        string s = RetrieveFromSession("key");
        // do something with s    
    }
 
    public string RetrieveFromSession(string key)
    {
        return HttpContext.Current.Session[key];
    }
 
    public void AddToSession(string key, string value)
    {
        HttpContext.Current.Session[key] = value;
    }
}

This simple extract method refactoring actually accomplished a great deal for this code. Primarily, we have now encapsulated our Session store behind some methods. If we want to change how this class works with Session, we are now only changing it in one method, rather than throughout the entire class. So, as we can see by performing one very small behavior preserving transformation to the code, we’ve increased its maintainability.

Lets move on to the next step to getting this code under test. As most anyone who has tried to get an HttpContext in an NUnit test can attest to, this is virtually impossible. Sure, I know there are numerous hacks available on how to accomplish this, however, our goal is two fold. First, to get it under test, and second to break dependencies.

So, how do you break this dependency? Let’s look at another refactoring called ExtractClass. Extract class is a small step that involves taking a method or group of methods and placing them into a new class.

Consider this:

public class SessionStore
{
    public string RetrieveFromSession(string key)
    {
        return HttpContext.Current.Session[key];
    }
 
    public void AddToSession(string key, string value)
    {
        HttpContext.Current.Session[key] = value;
    }
}
 
public class MyPage
{
    private SessionStore sessionStore = new SessionStore();
 
    public void Method1()
    {
        sessionStore.AddToSession("key");
    }
 
    public void Method2()
    {
        string s = sessionStore.RetrieveFromSession("key2");
        // do something with s    
    }
 
    public void Method3()
    {
        string s = sessionStore.RetrieveFromSession("key");
        // do something with s    
    }
}

All we’ve done in this example is move the RetrieveFromSession method into a new class called SessionStore. By doing this, we’ve encapsulated the Session store behind a class, so now it is not only available to the MyPage class, but the same store is available to the rest of the application as well.

Now, lets get this under test. To get this under test, we perform one more small behavior transforming step called Extract Interface. The Extract Interface refactoring is exactly what it says; create a new interface from a certain group of methods. This is where the magic happens to get this under test.

public interface ISessionStore
{
    string RetrieveFromSession(string key);
    void AddToSession(string key, string value);
}
 
public class SessionStore : ISessionStore
{
    public string RetrieveFromSession(string key)
    {
        return HttpContext.Current.Session[key];
    }
 
    public void AddToSession(string key, string value)
    {
        HttpContext.Current.Session[key] = value;
    }
}
 
public class MyPage
{
    private ISessionStore sessionStore = new SessionStore();
 
    public void Method1()
    {
        sessionStore.AddToSession("key", "value1");
    }
 
    public void Method2()
    {
        string s = sessionStore.RetrieveFromSession("key2");
        // do something with s    
    }
 
    public void Method3()
    {
        string s = sessionStore.RetrieveFromSession("key");
        // do something with s     
    }
}

We now have an interface that defines the behavior or contract that we expect from our SessionStore implementations. Doing this in conjunction with dependency injection allows us to very easily stub out a session store for use in our test project.

public class MyPage
{
    private ISessionStore sessionStore;
 
    public MyPage(ISessionStore sessionStore)
    {
        this.sessionStore = sessionStore;
    }
 
    // rest of code omitted for brevity
}
 
class StubSessionStore : ISessionStore
{
    private StringDictionary dict = new StringDictionary();
 
    public string RetrieveFromSession(string key)
    {
        return dict[key];
    }
 
    public void AddToSession(string key, string value)
    {
        dict[key] = value;
    }
}
 
[TestFixture]
class MyPageFixture
{
    [Test]
    public void TestMethod1()
    {
        ISessionStore sessionStore = new StubSessionStore();
        MyPage page = new MyPage(sessionStore);
        page.Method1();
 
        Assert.AreEqual("value1", sessionStore.RetrieveFromSession("key");
    }
}

Wow! What just happened?

This has now accomplished both of our goals. We are now able to bring the MyPage class under test, because we have broken the MyPage’s dependency on the HttpContext.Session store. The MyPage class takes an implementation of ISessionStore in its constructor and communicates with the session store via that interface, so no longer are we limited to using the options provided by ASP.NET. We also no longer have the dependency on the HttpContext in our test method, since we are providing our own implementation of ISessionStore to the class under test.

There are still more things that we could do with this particular piece of code. Primarily, since I think we all agree that string literals are a bad thing, we could go through and follow the same process to bring the literals into the ISessionStore interface so that we can access them as strongly typed members of the interface. This means that if we mistype it, the error will be caught at compile time as opposed to runtime.

As you can see, the refactoring of this application consisted of many small steps, which led us to the final outcome. It is very strongly recommended that you go through these smaller steps, as going from the first piece of code to the last when working with legacy code is bound to introduce errors. By performing the small steps, you are able to verify that no behavior was altered after each step. If something goes wrong, its much easier to roll back that single step as opposed to rolling back a whole gaggle of changes.

I hope that after reading this you have a better understanding of refactoring, if you’re new to it. If you’ve got a bit of experience with this, I hope that you find this worthy of sending to colleagues that may be new to the concept and are struggling with how to effectively use refactorings as part of their daily work.

3 Comments

My Development Environment

For the past two years, I’ve been doing all of my development work inside Virtual PC images, and have found that this suits me very well. I like the keeping my development environment isolated from the other, more mundane functions of my PC (such as Outlook). I’ve been storing all of my virtual machines on an 160gb external USB drive, which again has been working quite well. The drive spins fast enough (7200rpm) and has a large enough cache that I dont really notice a difference between running my IDE on the host PC.

Late yesterday afternoon, as I was in a hurry to get out the door, I started to shutdown my computer. Before the computer had completely shut down, I disconnected my external USB drive. Fast forward to this morning, and imagine my horror when I tried to load up my dev environment and found that the .vhd was *gone*.

I spent a good portion of the day looking at tools to recover this .vhd file, to no avail. The majority of the critical code that I was working on was thankfully committed to Subversion. Have I ever talked about the importance of source control? However, the panic set in when I realized how much stuff on there was not in SVN. Little one-off projects Id been working on to test ideas and so on.

It became immediately clear to me that I needed to keep my source code separate from the virtual pc image, but how would I go about doing that?

I stumbled across a neat feature in Virtual PC called ’shared folders’, which allows you to share a folder on your host pc and it can be accessed as a network share by the VPC image. This really seems to be the way to go.

So, I have a folder on my host pc called /shared. Within that folder, I have a folder called projects which now contains all of my source code for all my dev environments (VS.NET 2003 and VS.NET 2005).

As part of my backup plan now, that folder gets backed up and hopefully I never have to experience the agony of realizing that some valuable source code has been lost.

One thing I did notice is that because this runs through a network share, I had to adjust my .NET security policy to grant Local Intranet full trust permissions. Since I dont do anything but write code within the VM, I feel comfortable with granting that permission.

2 Comments

Camera RAW 3.3

Recently, I converted to shooting only RAW on my 20D, because of the greater control that I have over processing the image. As such, Ive been paying more attention to the Camera RAW updates available from Photoshop.

Recently, they have released version 3.3 of this tool, along with the DNG converter (windows | mac).

Enjoy!

No Comments

UI for long running requests

We have an application that given certain inputs can take quite a while to run. The previous solution that we had in place to let the user know what was going on was a popup window that went away after the page completed loading.

This solution has been wrought with problems, not the least of which was the numerous different alogrithms that popup blockers use. One of the worst problems with this technique was the popup window not going away if the task encountered an error.

Mark Wagner has a fantastic piece of code (demo) that hooks into the onbeforeunload event to overlay a processing message onto the page. The neat thing about this technique is that there is not much more to do, since everything is automatically unloaded when the next page loads.

This is a fantastic technique and I look forward to finding other useful places to use this.

On a side note, dont you find it funny that the Google popup blocker pops up a popup to tell you that popups are being blocked??

No Comments

Tortoise SVN 1.3

The great people responsible for TortoiseSVN have released version 1.3, and as I had hoped for in a previous post, they now have integrated the ugly ASP.NET _svn hack, and it is no longer an unsupported product.

To use this, you will need to set an environment variable SVN_ASP_DOT_NET_HACK, which will make TSVN use ‘_svn’ as the Subversion admin folders, instead of ‘.svn.

No Comments

Jack is Back

The new season of 24 started tonight, and all I can say is *wow*! I’ve been completely — 100% — hooked on this show since the first episode about 4 years ago.

Jack Bauer, is far and away the best character in any drama series. There is no better entertainment than watching Jack go apeshit on someone. I think that the primary reason for this is that I really believe that, whether we want to admit it or not, there are people like Jack working for *our* government, and its because of people like him that we are as safe as we are.

Today’s two hour premeire did not disappoint, and as promised everything did change within the first 10 minutes. There will be another two hour show tomorrow. Definately recommended.

No Comments

Database Basics

This is just too good to pass up.

Raymond Lewallen has started a weekly series about database basics; parts one (ACID model) and two (normalization) are available now.

Raymond is one of my favorite bloggers right now because of his excellent writing style. His style lends itself very well to educating people. You should really consider subscribing to his blog to get this series as well as his other informative posts.

No Comments
« Previous Entries
flag
Favorite Charity
wounded warrior project
Search
Social
  • mattberther on twitter
  • mattberther on linkedin
Syndication
Archives
  • January 2010
  • September 2009
  • July 2009
  • June 2009
  • February 2009
  • January 2009
  • December 2008
  • November 2008
  • September 2008
  • August 2008
  • June 2008
  • May 2008
  • April 2008
  • March 2008
  • February 2008
  • January 2008
  • December 2007
  • November 2007
  • October 2007
  • September 2007
  • August 2007
  • July 2007
  • June 2007
  • May 2007
  • April 2007
  • March 2007
  • February 2007
  • January 2007
  • December 2006
  • November 2006
  • October 2006
  • September 2006
  • August 2006
  • July 2006
  • June 2006
  • May 2006
  • April 2006
  • March 2006
  • February 2006
  • January 2006
  • December 2005
  • November 2005
  • October 2005
  • September 2005
  • August 2005
  • July 2005
  • June 2005
  • May 2005
  • April 2005
  • March 2005
  • February 2005
  • January 2005
  • December 2004
  • November 2004
  • October 2004
  • September 2004
  • August 2004
  • July 2004
  • June 2004
  • May 2004
  • April 2004
  • March 2004
  • February 2004
  • January 2004
  • December 2003
  • November 2003
  • October 2003
  • September 2003
  • August 2003
  • July 2003
  • June 2003
  • May 2003
  • April 2003
  • March 2003
mattberther.com © 2003 - 2010