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.
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.
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!
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.
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.
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.
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.
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? :)
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.
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?


