the home row

the home row | All posts by rob

Firing Events - Don’t repeat yourself

by Rob 12. June 2010 20:25

I've been working on a Silverlight application recently that has a provider layer which exposes lots of events. It became clear pretty quickly that we were violating DRY by using the same pattern again and again to fire the events. Here's a typical piece of code to fire one of the events:

private void OnMapLocationChange(Location location)
{
    var handler = this.MapLocationChanged;

    if (handler != null)
    {
        handler(this, new MapLocationChangeEventArgs(location));
    }
}

The method assigns the event handler to a local variable, which stops problems with the handler being nulled whilst the method is executing. It then checks that the handler isn't null. And then finally calls the event handler to fire the event with a new EventArgs object.

Looking at these methods the only thing that differed was the type of event they dealt with. The duplication can be removed easily with a generic method. The method takes the event handler that will be called. We don't need to know the type of the event until compile time so we can set it to be generic. We then add a Func delegate which has the responsibility of creating the event argument. The event argument could have been passed in directly but this would mean that the object was constructed unnecessarily if the event handler is null. Here's the method I came up with.

public static void FireEvent<T>(this EventHandler<T> eventHandler, object sender, Func<T> createEventArgs)
    where T : EventArgs
{
    var handler = eventHandler;

    if (handler != null)
    {
        handler(sender, createEventArgs());
    }
}

You've probably noticed that it's an extension method. I've used an extension method so we can hang it straight off the event handler which gives us this very tidy option for firing the events:

this.MapLocationChanged.FireEvent(this, () => new MapLocationChangedEventArgs(location));

Tags:

Capturing arguments from multiple method calls in Rhino Mocks

by Rob 20. March 2010 15:55

I'm a big fan of Rhino Mocks. I've been using it regularly over the past year or two. But I always seem to be finding new functionality. The latest came about from a conversation with a colleague. They wanted to assert that multiple calls were made to a method. This is a common scenario and can be tested by using the following syntax.

sut.AssertWasCalled(thing => thing.DoSomething(Arg<int>.Is.Anything), options => options.Repeat.Times(4));

But the requirement went further to say that they needed to check that for the three calls that were made they each passed a specific ID. After a little research we came across GetArgumentsForCallsMadeOn method. This allows you to access the parameters of each call to the method on your mocked object. Here's some code to show how this works:

[TestClass]
public class when_i_call_something_twice_i_can_take_a_look_at_both_arguements : context_base
{
    protected override IThing  create_sut()
    {
        return MockRepository.GenerateStub<IThing>();
    }

    protected override void  because()
    {
        sut.DoSomething(15);
        sut.DoSomething(20);
    }

    [TestMethod]
    public void should_tell_me_that_arg_one_is_15()
    {
        sut.GetArgumentsForCallsMadeOn(thing => thing.DoSomething(Arg<int>.Is.Anything))[0][0].should_be_equal_to(15);
    }

    [TestMethod]
    public void should_tell_me_that_arg_two_is_20()
    {
        sut.GetArgumentsForCallsMadeOn(thing => thing.DoSomething(Arg<int>.Is.Anything))[1][0].should_be_equal_to(20);
    }
}

 

 

The indexer [0][0] refers to the [first method call][first argument] and then in the second test [second method call][first argument]. Some of the syntactic sugar in this example comes from JP Boodhoo’s BDD library.

Tags: ,

Unity - GetRootException extension method

by Rob 17. February 2010 00:27

One of the complaints I hear regularly is that debugging container resolution exceptions can be difficult. Well, unknown to many Unity has a handy extension method that helps you with this very problem. GetRootException can be found in the  Microsoft.Practices.Composite.ExceptionExtensions class. The method loops through inner exceptions to find the likely place that the most relevant exception took place. Below you can see three constructors for classes that are composed together. All should resolve except that the ApplicationCommands class takes an interface IInterfaceWeForgetToAdd that doesn’t have an implementation added to the container.

public Shell(IShellViewModel shellViewModel)
public ShellViewModel(IApplicationCommands commands, IEnumerable<IMenuItemViewModel> menuItems)
public ApplicationCommands(IRegionManager regionManager, IInterfaceWeForgetToAdd iwfta)

Below is a screen shot of where you’d need to dig around to find the relevant exception message that tells you what the problem is when resolving the Shell.

image

 

 

Or alternatively you can call the GetRootException extension method on the caught exception and then look at the message to get the following useful pointer to where things went wrong:

"The current type, Contracts.Services.IInterfaceWeForget, is an interface and cannot be constructed. Are you missing a type mapping?"

Tags:

Visual Studio 2010 – Adding zoom keyboard shortcuts

by Rob 4. February 2010 23:34

Visual Studio 2010 has now incorporated the ability to zoom in and zoom out of the editor. This feature is activated by holding down the control key and using the mouse wheel to zoom in and out. The image below shows the editor zoomed in to 345%, which is displayed in the bottom left corner.

Editor zoomed in to 345%

If you're a keyboarder  like me then you'll be wanting to know how this can be achieved without using the mouse. The default settings don't support this, but you can easily map the correct commands to keyboard shortcuts. The commands you’ll need to map are:

view.zoomin

view.zoomout

These can be set through Tools > Options > Environment > Keyboard

Options to set zoomin keyboard shortcut

Tags: ,

Convert a path or file name to Dos 8.3 format with AutoHotkey

by Rob 28. January 2010 05:36

It comes about now and again that you need to get an old style Dos 8.3 file or path name to satisfy some legacy application or to represent a standard path without the blank spaces in it. Here's an example of a Dos 8.3 path to Spotify in my Dropbox:

C:\Mydrop~1\Apps\spotify\spotify.exe

The path you'd normally see would be:

C:\My Dropbox\Apps\spotify\spotify.exe

If I tried to launch the normal link from the command line it'd fail because it wouldn't be able to resolve the path correctly.

But using the shortened Dos version causes no problems because it doesn't contain any spaces. So rather than trying to wrap the standard path in quotes for a program that isn't expecting spaces you can pass the Dos 8.3 path instead.

Here's an AutoHotkey script that will take the current highlighted text, copy it to the clipboard, convert it to the Dos 8.3 path and paste back to the clipboard.

capslock & d::
Send ^c
ClipWait,1
If Errorlevel
{
    MsgBox, Error copying to the clipboard!
    return
}

newPath := GetShortPath(Clipboard)
if newPath =
{
    MsgBox, To Dos Path - Invalid source path!
}

Clipboard := newPath
ClipWait, 1
If Errorlevel
{
    MsgBox, Error pasting to the clipboard!
    return
}

return

GetShortPath(LongPath) {
Loop, %LongPath%, 1
Return A_LoopFileShortpath
}

The script is fired by pressing capslock & d. If the path is incorrect, there are problems accessing the clipboard or no text is highlighted the script will inform you with a message box. If everything goes as planned then the new shortened path will be silently copied to the clipboard. Take a look at the AutoHotkey documentation if you’d like to change this to a different keyboard shortcut.

Tags:

Visual Studio 2010: Remapping - Move between highlighted references

by Rob 24. January 2010 17:13

I've recently been following the Is This Thing On - Visual Studio 2010 tip of the day series. I highly recommend subscribing. The best tip yet was around Reference highlighting. In a nut shell every time you move over a symbol all instances are highlighted. You can see below that all references have been highlighted for MainWindow:

image

Once the symbols have been highlighted you can move to the next occurrence with Ctrl+Shift+Down Arrow and move to the previous occurrence with Ctrl+Shift+Up Arrow. For ViEmu users it will be unnatural to reach over for the arrow keys, so it's time to remap these using AutoHotkey. The idea is based on this blog post by JP Boodhoo where he maps ReSharper Go to next member to Alt+J and ReSharper Go to Previous Member to Alt+K. So here’s the update you need for your AutoHotkey script:

$^+k:: send, ^+{up}

$^+j:: send, ^+{down}

This will map Ctrl+Shift+J to Ctrl+Shift+Down Arrow and Ctrl+Shift+K to Ctrl+Shift+Up Arrow. Now you can happily move between highlighted references without leaving the home row.

Enjoy

Tags: ,

Open a file into an existing instance of GVim

by Rob 16. January 2010 14:47

I use GVim a lot for editing most types of files. More than likely I'll launch files straight from a command line. One problem with this method is that each file appears in a new instance of GVim. This can quickly become difficult to manage. You can solve this problem by using the clientserver feature of GVim. Below is what the documentation says about clientserver functionality.

When compiled with the |+clientserver| option, Vim can act as a command server. It accepts messages from a client and executes them.

This means that your shell of choice can act as a client and fire commands to an existing instance of GVim. I use PowerShell ISE for simple file operations and launch all my programs from there. To launch a named server instance of GVim I run the following command:

C:\Mydrop~1\Apps\gVimPortable\gVimPortable.exe --servername gvim

I keep GVim in my DropBoxso it moves with me to other computers. So you'll need to edit the path to the location of GVim on your computer. The servername argument is set to the name gvim, but you can set this to anything you like.

Now when you wish to open a new tab in this instance run the following command:

C:\Mydrop~1\Apps\gVimPortable\gVimPortable.exe --servername GVIM --remote-tab .\main.ahk

In my case this launches the main AutoHotkey script into a new tab in the existing instance of GVim. You may be thinking this will mean more typing and ultimately take more time. To speed this whole process up I store a couple of snippets in an AutoHotkey script. This allows me to type "gvit" and expand this out to:

C:\Mydrop~1\Apps\gVimPortable\gVimPortable.exe --servername GVIM --remote-tab

I can then just add the file name to the end of the command to launch into my gvim instance. Not everyone's cup of tea, but I hope someone will find this useful. To find out more about snippets in AutoHotkey you can take a look at another of my blog posts.

 

del.icio.us Tags: ,

Tags: ,

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen

About the author

Rob Henry - .Net Developer and Keyboard Junkie

Page List