Monthly Archives: July 2010
Open VS 2010 Command Prompt Here

I wanted to add an “Open VS 2010 Command Prompt Here” option to the context menu in windows explorer. To do this, create a text file with a .reg extension, paste in the text below, save the file, then double-click it to run it against your registry.

This example was adapted from here.

Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOTDirectoryBackgroundshellVS2010 Command Prompt]
@=”Open VS2010 Command Prompt Here”
“Extended”=””
“NoWorkingDirectory”=””
[HKEY_CLASSES_ROOTDirectoryBackgroundshellVS2010 Command Promptcommand]
@=”C:\Windows\System32\cmd.exe /s /k “pushd %V && “C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat”” x86 “
[HKEY_CLASSES_ROOTDirectoryshellVS2010 Command Prompt]
@=”Open VS2010 Command Prompt Here”
[HKEY_CLASSES_ROOTDirectoryshellVS2010 Command Promptcommand]
@=”C:\Windows\System32\cmd.exe /s /k “pushd %V && “C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat”” x86 “
[HKEY_CLASSES_ROOTDriveshellVS2010 Command Prompt]
@=”Open VS2010 Command Prompt Here”
“Extended”=””
“NoWorkingDirectory”=””
[HKEY_CLASSES_ROOTDriveshellVS2010 Command Promptcommand]
@=”C:\Windows\System32\cmd.exe /s /k “pushd %V && “C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat”” x86 “
Martin Fowler on Why Agile Works

The intro is in French, but the talk is in English. Enjoy!

<!–

Pourquoi, pas comment
Pourquoi, pas comment

USI 2010 : conférence incontournable du l’IT en France
Rendez-vous annuel des Geeks et des Boss souhaitant une informatique qui transforme nos sociétés, USI est une conférence de 2 jours sur les sujets IT : Architecture de SI, Cloud Computing, iPhone, Agile, Lean management, Java, .net… USI 2010 a rassemblé 500 personnes autour d’un programme en 4 thèmes : Innovant, Durable, Ouvert et Valeur.
Plus d’informations sur www.universite-du-si.com

Yodelay Project Structure Update

I’ve been exposed to some better repository organization lately. In response to what I’ve learned, I’ve updated the yodelay project structure to make it easier to build with the external dependencies. It seems obvious in retrospect :-). The new structure looks like this:

 

/     // source root

/src // directory for project source code

/libs // directory for non-Framework assembly dependencies

This should make it possible to download and build whether or not you have already installed NUnit and Rhino mocks on your machine.

Razor

Scott Gu just announced a new view engine called “Razor” for ASP .NET MVC, and it looks really sweet! Check it out here. I can’t wait to get my hands on the beta!

ObservableCollectionHandler & ChangeTracker

When working with the ObservableCollection or INotifyCollectionChanged interface, it is common to see code like the following:

void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    switch (e.Action)
    {
        case NotifyCollectionChangedAction.Add:
            HandleAddedItems(e);
            break;

        case NotifyCollectionChangedAction.Move:
            break;

        case NotifyCollectionChangedAction.Remove:
            HandleRemovedItems(e);
            break;

        case NotifyCollectionChangedAction.Replace:
            HandleReplacedItems(e);
            break;

        case NotifyCollectionChangedAction.Reset:
            HandleClearItems(e);
            break;
    }
}

There’s nothing particularly wrong with this code except that it’s kind of bulky, and that it starts to crop up all over your application. There’s another problem that’s not immediately obvious. The “Reset” action only gets fired when the ObservableCollection is cleared, but it’s eventargs does not contain the items that were removed from the collection. If your logic calls for processing removed items when they’re cleared, the built-in API offers you nothing. You have to do your own shadow copy of the collection so that you can respond to the Clear() correctly.

For that reason I wrote and added ObservableCollectionHandler to manage these events for you. It accepts three kinds of delegates for responding to changes in the source collection: ItemAdded, ItemRemoved, and ItemReplaced actions. (It would be easy to add ItemMoved as well, but I have seldom had a need for that so I coded the critical path first.) The handler maintains a shadow copy of the list so that the ItemRemoved delegates are called in response to the Clear() command.

[Test]
public void OnItemAdded_ShouldPerformAction()
{
    // Arrange: Setup the test context
    int i = 0;
    var collection = new ObservableCollection<Employee>();
    var handler = new ObservableCollectionHandler<Employee>(collection)
        .OnItemAdded(e => i++);

    // Act: Perform the action under test
    collection.Add(new Employee());

    // Assert: Verify the results of the action.
    Require.That(i).IsEqualTo(1);
}

Another common need with respect to ObservableCollections is the need to track which items were added, modified, and removed from the source collection. To facilitate this need I wrote the ChangeTracker class. ChangeTracker makes use of ObservableCollectionHandler to setup activities in response to changes in the source collection. ChangeTracker maintains a list of additions and removals from the source collection. It can also maintain a list of modified items assuming the items in the collection implement INotifyPropertyChanged.

Here is a sample unit test indicating it’s usage:

[Test]
public void GetChanges_AfterAdd_ShouldReturnAddedItems()
{
    // Arrange: Setup the test context
    var source = new ObservableCollection<Employee>();
    var tracker = new ChangeTracker<Employee>(source);

    // Act: Perform the action under test
    var added = new Employee();
    source.Add(added);

    // Assert: Verify the results of the action.
    var changes = tracker.GetChanges(ChangeType.All);
    Require.That(changes.Any()).IsTrue();
    Require.That(tracker.HasChanges).IsTrue();

    var change = changes.First();
    Require.That(change).IsNotNull();
    Require.That(change.Type).IsEqualTo(ChangeType.Add);
    Require.That(change.Value).IsTheSameAs(added);
}

The full source code and unit tests can be found here.