logo
  • Jobs
  • About Me
  • Contact
  • Home

Archive for March, 2006

« Previous Entries

Feed Demon Support Staff

Recently, I started using FeedDemon as my RSS aggregator, having quickly fallen in love with the features present in the product. Nick and Greg from Newsgator have really done a tremendous job in bringing forward such a valuable product.

I ended up purchasing it while I was using the 2.0 betas, and there was some quirkiness while I was using it, although I just blew those things off to running beta software. However, I did have a pesky issue where I would get a dialog everytime I started FeedDemon which claimed the serial number was incorrect for this version.

I sent an email to the NewsGator support team, and got a prompt response from Jack (Brewster) who walked me through some basic steps in trying to get this resolved. Jack was very patient and never once seemed phased by my level of frustrations, which was wonderful to see in a support person. Ultimately, it ended up being something that got goofed up w/ my newsgator online account, which was probably something I did.

What I really want to say is thank you to the Newsgator team which made my support request very positive. This is fairly rare in the tech industry, and certainly is something I hope you dont lose.

2 Comments

Unattended Children

One of the funnier things Ive seen in a long time came through my email box today. It was a picture of what is likely the best ever sign inside of a store.

Click on the thumbnail for a full size image.

1 Comment

Password Tracking

I’ve been using PWSafe for quite a while to track my passwords, but I always felt something was lacking. Today, I finally decided that I needed to look and see what else is out there.

I stumbled across KeePass Password Safe, which incidentally has won quite a few awards in the security arena. Some things that make this much better than PWSafe are a much improved GUI. A lot more things can be set up, such as password expiring. This is really cool, especially considering that a lot of people use the same password all over the place. This tool reminds you to change those up every once in a while, which is certainly a good security practice.

The two best parts about it: it was able to import all of my PWSafe passwords, and its free! Go check it out!

No Comments

Resume Pet Peeve

My company, Healthwise, is going through a tremendous growth and we are looking at almost doubling our development staff. Part of my responsibilities for my new role as Software Engineering Manager include culling resumes to determine who makes it to the phone screening.

The quality, or lack thereof, of some of the resumes I’ve seen is astounding. As obvious as this sounds there is one thing that you can do to increase your chances of the resume making it further into the process.

Proofread your resume and cover letter. There is nothing that will make me reject your resume quicker than a resume or cover letter that has grammatical or typographical errors. If you can’t take the time to make sure that you’re submitting a quality product when applying for a job, how can I know that you will actually deliver quality for our organization.

1 Comment

Woke up this morning … got yourself a gun

Most people will catch that reference to American pop culture… I just finished watching the Sopranos which was recorded on my Tivo from last night.

I’ve been waiting for this show for two years now, and I have to say it did not disappoint. The show ended with a bang, and I can hardly wait for next week.

No Comments

Drew Lewallen

I saw a post from Raymond Lewallen earlier today announcing the birth of his son. Eagerly, I went to his site to wish my congratulations.

I have to say I was not ready for what I saw. It seems that Drew was born with some serious complications and is currently on a heart/lung bypass machine that is breathing and pumping for him.

I want to take this opportunity to let the Lewallen’s know that they are in my prayers, and I also encourage each of my readers to say a special prayer for Drew.

God bless you and your family through this tough time, Raymond. You are in our thoughts and prayers.

No Comments

Simian and CruiseControl.NET

I’ve been using Simian for quite a while to analyze code and help me find areas that could use refactoring. However, only recently have I introduced Simian into my continuous integration process here at home. I had quite a time getting builds to work after doing this.

The easiest way to get Simian into CC.NET is to set up an exec task in your ccnet.config file’s task section, as follows:

<project>
    <tasks>
        <exec>
            <executable>c:\tools\simian\bin\simian-2.2.8.exe</executable>
            <buildArgs>-recurse=*.cs -formatter=xml:build\log\simian.xml</buildArgs>
        </exec>
    </tasks>
</project>

Id noticed that quite often builds would fail for no apparent reason. The CC.NET log looked clean. Finally, after reviewing one of my successful builds I noticed the simian section had an area that said ‘failOnDuplication=true’.

Assuming that this was my problem, I looked into it a little further. Seems that simian is by default set up to return 1 on duplications, which triggers a failure in both nant and cc.net.

The easiest way to get around this is to pass another argument in your build args section:

-recurse=*.cs -formatter=xml:build\log\simian.xml -failOnDuplication-

Problem solved! :)

I understand the reasons for having simian fail on duplication, however, I disagree with this being the default. I hope that this will change in a future build.

2 Comments

Testing MVP with Rhino.Mocks

I’ve been working on a project recently where I’ve decided to use Model View Presenter (MVP). The biggest benefit to implementing using MVP is that you end up decoupling your views from your presenters since all communication from the view to the presenter happens via events.

Since all your views are defined as interfaces, this can turn out to be an absolute bear to unit test. To raise an event, you actually have to have a concrete implementation that fires the event.

public interface IView
{
    event EventHandler ItemSelected;
    void SetItem(object o);
}
 
[Test]
public void TestItemSelected()
{
    TestableView view = new TestableView();
    Presenter subject = new Presenter(view);
    view.FireItemSelected();
 
    Assert.IsTrue(view.ItemSet);
}
 
private class TestableView : IView
{
    public event EventHandler ItemSelected;
    public bool ItemSet = false;
 
    public void SetItem(object o)
    {
        ItemSet = true;
    }
 
    public void FireItemSelected()
    {
        ItemSelected(this, EventArgs.Empty);
    }
}

Pretty straightforward, but what a colossal PITA. Not only do we have to implement a TestableView to fire the event which triggers everything in the presenter, but also we have to put a property on that implementation so we can verify that the presenter actually did what was expected.

Earlier today, a coworker pointed me at a fantastic class that utilizes Rhino.Mocks to make this *much* easier. Take a look at this gem by Geert Baeyaert.

using System;
using Rhino.Mocks;
 
public interface IEvent
{
    void Raise(object sender, TEventArgs args);
}
 
public static class LastEvent
{
    public static IEvent Get() where TEventArgs : EventArgs
    {
        return new Event, TEventArgs>();
    }
 
    public static IEvent Get() where TEventArgs : EventArgs
    {
        return new Event();
    }
 
    private class Event : IEvent where TEventArgs : EventArgs
    {
        public Event()
        {
            if (!typeof (Delegate).IsAssignableFrom(typeof (TEventHandler)))
            {
                throw new
                    Exception("TEventHandler should be a delegate type");
            }
 
            LastCall.Callback((Predicate)
                              delegate(TEventHandler handler)
                                  {
                                      // First check if the handler is of type EventHandler
                                      EventHandler newHandler = handler as EventHandler;
                                      if (newHandler == null)
                                      {
                                          // It's not an EventHandler, so we wrap a new delegate around it that is of type EventHandler
                                          newHandler = delegate(object sender, TEventArgs e)
                                                           {
                                                               // In this new delegate, we dynamically invoke the original delegate.
 
                                                               ((Delegate) (object) handler).DynamicInvoke(
                                                                   new object[] {sender, e});
                                                           };
                                      }
 
                                      handlers += newHandler;
                                      return true;
                                  });
        }
 
        private EventHandler handlers;
 
        public void Raise(object sender, TEventArgs eventArgs)
        {
            EventHandler temp = handlers;
            if (temp != null) temp(sender, eventArgs);
        }
    }
}

Now the test described above looks more like this:

[Test]
public void TestItemSelected()
{
    using (MockRepository mocks = new MockRepository())
    {
        IView view = mocks.CreateMock();
        view.ItemSelected += null;
        IEvent handler = LastEvent.Get();
        view.SetItem(null);
        LastCall.IgnoreArguments();
        mocks.ReplayAll();
 
        handler.Raise(this, EventArgs.Empty);
        mocks.VerifyAll();
    }
}

This utilizes the Rhino.Mocks framework and the generic capability of .NET 2.0 allowing me to fire off the event without creating a subclass to do so. I also dont need to create the subclass to check that the presenter did what it was supposed to, because I was able to set up an expectation for view.SetItem to be called.

I love tools that make my life easier, and Im quickly seeing that Rhino.Mocks is just one of those things. Great work, Ayende… Now, can we get LastEvent incorporated into the core Rhino.Mocks project? :)

2 Comments

Goodbye, Acrobat Reader

Im a little late to the game with this, so this is for those who havent heard of Foxit Reader.

Are you tired of Adobe Reader, and all of the extra crap that gets bundled with it (ie: Yahoo search, and all sorts of plugins that youll never use)? Take a look at Foxit Reader! A single executable file comprises the entire application. Installation steps are extracting the .zip file, and double clicking the contained executable. The program can register itself as the default handler for PDF files.

Very cool too… Im in the process of uninstalling Acrobat Reader right now.

No Comments

BackgroundWorker component

More and more, Im spending time in .NET 2.0 and more and more Im finding *really* cool things. The latest one I found was the BackgroundWorker component. This is probably old hat to most of you, but I was really impressed to see this. From the MSDN documentation:

The BackgroundWorker class allows you to run an operation on a separate, dedicated thread. Time-consuming operations like downloads and database transactions can cause your user interface (UI) to seem as though it has stopped responding while they are running. When you want a responsive UI and you are faced with long delays associated with such operations, the BackgroundWorker class provides a convenient solution.

To execute a time-consuming operation in the background, create a BackgroundWorker and listen for events that report the progress of your operation and signal when your operation is finished. You can create the BackgroundWorker programmatically or you can drag it onto your form from the Components tab of the Toolbox. If you create the BackgroundWorker in the Windows Forms Designer, it will appear in the Component Tray, and its properties will be displayed in the Properties window.

To set up for a background operation, add an event handler for the DoWork event. Call your time-consuming operation in this event handler. To start the operation, call RunWorkerAsync. To receive notifications of progress updates, handle the ProgressChanged event. To receive a notification when the operation is completed, handle the RunWorkerCompleted event.

Instantiating code on a background thread is as simple as this:

private void button1_Click(object sender, EventArgs e)
{
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += new DoWorkEventHandler(worker_DoWork);
    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
    worker.RunWorkerAsync();
}
 
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
    // This is the method that gets executed on a background thread.
    // Since you should not update the UI from a thread, make sure
    // you use the RunWorkerCompleted handler if you need to do that.
    // You can assign e.Result to a value which can be used in that handler.
    SomeLongRunningWebServiceCall();
}
 
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // this is back on the main UI thread, so you can update the UI
    // e.Result is assigned to whatever you've assigned it to in the
    // DoWork handler
}

How cool and easy is that?

4 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