www.codinghillbilly.com   kyle.baley.org  Subscribe / Contact
 
 
 
 
LATEST POSTS
Sunday, September 02, 2007

I recently attended John Bristowe's presentation on Silverlight. He was great as always and gave a good overview of the technology but I left the room not being as excited about Silverlight as I was when I went in.

Which isn't to say I'm not stoked about it. I'm a big AJAX fan and the idea of doing some of the more complicated or labour-intensive stuff in managed code is appealing. But there has been a tremendous amount of buzz on Silverlight. I've been following Tim Heuer's recent adventures in it with a tinge of jealousy because I'm still not playing with it a lot. And when Ray Ozzie touts the next big thing, people listen.

I had done my own "hello world" app early on and was suitably impressed. In the intervening months, the buzz just kept growing and growing to the point where I went into the presentation trying to see what else there was to it. I knew it was being positioned as a Flash-killer (or at least that's what the buzz was) but I had to see what I had missed in my XAML.

Turns it out, not much. Yes, it's a Flash-killer (whether John wants to say the words or not) but as far as I can tell, that's it. At the end, I was scratching my head about why everyone was so worked up about it. You're still working with textboxes and input buttons and wiring up the events the same way you would in HTML and Javascript, albeit in a *much* easier way. And probably prettier too once the designers get hold of this. You still have the same security limitations of Javascript. In particular, you still can't call webservices outside your domain. (This was one of the problems I thought Silverlight may have solved. They're working on it but for the moment at least, you still need to call back to your own domain.)

The essence of my puzzlement is that I don't understand why so many people think this is going to revolutionize the web. I mean that as a genuine question, not a cynical dig. Is it because of the presentation-aspect? That Silverlight can make apps that much more appealing visually? If so, how is it different than Flash? To be sure, the airline demo *is* impressive (and I sincerely hope someone is making an effort to do a real-world version of it).

I dunno, maybe I am underestimating the popularity of Flash. It doesn't seem like a very threatening technology to kill off. I'm probably not recognizing the value of the media-centred features of Silverlight as well. This is probably the big selling point for the executives at Microsoft, especially in an era where YouTube can be sold for $1.65b.

More likely, I'm probably underestimating the pain new web developers are feeling trying to get Javascript to do things people have come to expect from their web apps. Early in the presentation, John asked, "Who *likes* working with HTML, CSS, and Javascript?" It was a loaded question and I didn't want to get him off-track early in the presentation but to be honest, I do. Not at the expense of "real" development but I actually don't mind diving into Fiddler with XMLHTTPRequest objects, spewing alerts all over the screen. Not all day, every day but I like mucking with the DOM in a crappy dynamic language once in a while. It's my version of slumming it.

Silverlight is still in the top three on my technology wish list. I can think of quite a few applications that could benefit from it, not the least of which is the near-defunct music player I work on in fits of ambition. So I'll fiddle around with it in the coming months because it fits with my sensibilities. And if I'm lucky, it'll be as popular as everyone says it will and I'll be able to keep the young'un fed for the next couple of years.

Kyle the Aligned

Monday, May 21, 2007

This is part moot of inconsequential posts on my professional development odyssey in which I try to develop an online music library application using whatever techniques and technology strike my fancy at the time. Code can be found at: svn://208.109.223.228/Suvius.Flamingo if memory serves.

In our last episode, I popped up an initial test to see if we could retrieve all songs by an artist. I've since added a test, ShouldBeAbleToRetrieveSongsWithPartialTitle, that tests to see if we can retrieve songs by title (or partial title). It's not altogether interesting so I'll skip it here.

The next test was ShouldBeAbleToRetrieveSongsByGenre which garners slightly more air time because if the notion of a Genre. Here is the test in its current incarnation:

  [ Test ]
  public void ShouldBeAbleToRetrieveSongsByGenre( )
  {
      Genre genre = new Genre( "Really &*%$ old" );
      int numberOfSongs = songRepository.GetSongsByGenre( genre ).Count;
      using ( mockery.Record( ) )
      {
          ISong fakeSong = mockery.DynamicMock<ISong>( );
          SetupResult.For( fakeSong.Genre ).Return( genre );
          songRepository.AddSong( fakeSong );
      }
      Assert.AreEqual( numberOfSongs + 1, 
songRepository.GetSongsByGenre(
new Genre(
"Really &*%$ old" ) ).Count ); }

And here is the GetSongsByGenre method:

    public IList<ISong> GetSongsByGenre( Genre genre )
    {
        List<ISong> songsWithGenre = new List<ISong>( );
        foreach ( ISong song in songList )
        {
            if ( song.Genre.Equals( genre ) )
            {
                songsWithGenre.Add( song );
            }
        }

        return songsWithGenre;
    }

(NOTE: No this isn't my final implementation. But it's enough to pass the tests for now.)

I've decided to make the Genre a Value Object which you might be able to determine from the comparison in GetSongsByGenre. The inital reason for this is that a Genre seems like it should be an object and I'd like to be able to compare two songs' genres.

But as I write this, I realize I probably should apply the same thinking to an artist. If a genre is to be its own object, why not use an Artist object rather than a string? For the purpose of our application, both are to be used identically (i.e. as search criteria and metadata on a song).

So I should create an Artist object, yesno? Now it's starting to sound more complicated than it probably needs it to be. Do I care about genres or artists other than as a property on the song? Is there any other data about them that is interesting to me?

At this point, I'd say the answer is no. Certainly for genres. But also for artists for the moment. Maybe we'll get to the point where we want to store the names, birthdates, country, aliases, and a little bio on each one but for now, I believe it's time to demote Genres back to a string.

Kyle the Devalued

Thursday, May 17, 2007

Here's the Subversion info for the online music app I keep referring to sporadically as Flamingo: svn://208.109.223.228/Suvius.Flamingo.

A couple of notes on the project structure:

  • The initial solution was created by TreeSurgeon, whose cause was recently taken up by Bil Simser
  • The build file was subsequently modified to account for the fact that TreeSurgeon's NAnt file doesn't work for .NET 2.0 solutions. It was borrowed heavily from various demos by JP. I've removed the deploy dependency from the "all" target because there is nothing to deploy yet. Have also add an <nunit2report> task because for the most part, Hillbillies don't like to read XML natively.
  • I'm using Rhino Mocks 3.1 which is where the funky new mockery.Record( ) functionality comes in.

So download the code and follow along with my professional development and we can explore the various definitions of the word "mock". Keep in mind that this series of posts differs from other demos in that it isn't a demo. It's a record of my learning shiny new things. By no means am I suggesting what I'm doing is a de facto standard or even a smart way of doing things. Quite the contrary, I encourage you to call me out if something doesn't look right.

The astute reader will probably guess that I have just finished reading Jimmy Nilsson's Applied Domain Driven Design and Patterns. Well, you'd be wrong. I'm still a couple of chapters from the end.

With that, let's get started. The solution contains two projects: Domain.Test and Domain. Like all the hot shot TDDers I'm trying to emulate, I started with a test:

[ Test ]
public void ShouldBeAbleToRetrieveSongsByAnArtist( )
{
    string artist = "Frank Crummitt";
    int numberOfCrummittSongs = songRepository.GetSongsByArtist( artist ).Count;
    MockRepository mockery = new MockRepository( );
    using ( mockery.Record( ) )
    {
        ISong fakeSong = mockery.DynamicMock<ISong>( );
        SetupResult.For( fakeSong.Artist ).Return( artist );
        songRepository.AddSong( fakeSong );
    }

    Assert.AreEqual( numberOfCrummittSongs + 1, 
songRepository.GetSongsByArtist( artist ).Count ); }

This led to the ISong interface and the SongRepository class, both of which are in the Domain project and neither of which I think belong there. ISong probably should go in a separate Domain.Interfaces project. SongRepository...well, I haven't decided yet.

Pay no notice if the Song class. It shouldn't be there yet because there is no code testing it (which you can verify by executing the "coverage" target in the build file). I've added it because I keep forgetting the API for the UltraID3 library and I left some sample code in the Song's constructor as a reminder.

Incidentally, in case it's not readily obvious, I'm starting with the requirement: Should be able to retrieve songs by an artist.

Some comments on the process to date. Firstly, it's not as easy as it looks coming up with initial tests. It's odd that I've written a test about song objects and still don't need a Song class. Even as I look at the test I've written, I'm wondering if there shouldn't be another to test SongRepository.AddSong.

Secondly, after reading what Nilsson had to go through to create fake objects in his book, I have an even greater appreciation of Rhino Mocks. Here's hoping Oren Eini doesn't get hit by a bus.

But overall, I'm happy with how things have started out. It took a bit to understand the build files I pilfered from JP enough to make my own changes to it but it's effort that translates directly to time saved on future projects.

Kyle the Initialized

Thursday, May 17, 2007

The Suvius.Flamingo project is not quite dead although it is, to go with the motif of the National Geograhic show playing behind me, about ninety percent down the python's gullet. But let's see what we can't glean from the carcass.

I haven't linked to the application because I'm scared to even check to see if it still works. Last I checked, Windows Media Player 11 had made the application all but useless so I kind of abandoned it. Now, in a fit of PD, I'm going to see if we can't all learn something from resurrecting the app and re-doing it in a TDD way. So with that, I shall carefully document its development from start to finish. Or at least until something else shiny catches my eye.

For those that want to play along, I have a Subversion repository and will post the details for it in the near future once I have created a read-only user. If you *really* want to gain my undying gratitude, roll up your sleeves and ping me to become a developer on the project.

The primary goal is learning. If we end up with a working application at the end, all the better.

First, the boring part: defining what the application is supposed to do. This will be a moving target but in a good way. Mostly because I'm reserving the right to change the requirements to make development (and blog topics) more interesting.

At a high level, I'm looking at building a front-end to my online music library. It currently resides at http://radio.baley.org as a directory list of about 300 songs. The other 2500 have yet to be migrated to the new server.

If I were to free associate some features, they would include:

  • Ability to search for music based on one or more criteria, including title, artist, and genre
  • Ability to chain search filters together to form a playlist
  • Ability to play the playlist in at least one popular media player in a user-friendly way
  • Ability to save a playlist
  • Ability for an administrator to upload additional songs to the database and glean the metadata from it (as opposed to keying it in manually)
  • Ability to update metadata and have it persisted not only in the database but in the underlying file as well
  • Ability for users to rate a song

Woman, I'd better stop there or I'll be here all night. Suffice it to say, there is a lot more I could throw in....ah, what the hell:

  • Ability for any user to tag a song with keywords
  • Ability to search based on tags
  • Ability to apply more than one genre, artist, album, etc to a song. This might be combined with the tagging feature. E.g. Wish You Were Here would be tagged with Pink Floyd, Roger Waters, David Gilmour, Rick Wright, Nick Mason, Wish You Were Here (album), A Collection of Great Dance Songs (album), classic rock, acoustic
  • Ability for users to add comments about a song (possibly in a wiki-like fashion)
  • Ability to share playlists
  • Ability to link songs (i.e. link to other versions of a song). This would also be user-driven

Let the music begin.

Thursday, November 23, 2006

Looking through the features of Windows Media Player 11, one might think that they have something against Hillbillies. Firstly, they appear to have made playlist management much more intuitive. Or at least they claim to on the website. I haven't actually played with any of the new features yet.

This kind of reduces the impact of what I had planned for Flamingo, which was to have playlists as sort of a combination of saved searchs, not a static list of songs. That way, you could add songs by artists you like and not have to redo your playlist.

If it were just that, though, it wouldn't be too big a deal. Especially given that I'm not pursuing any sort of commercial venture with this. The problem is, not only has WMP 11 undermined my efforts with features that are six versions too late, it also completely changes how Flamingo currently works.

With WMP 10, you would select a bunch of songs, click Play, and that list of songs would appear in the Now Playing list. With WMP 11, instead of a list of songs in the Now Playing list, you get a single entry that says Default.

The songs still play, mind you. But you can't see which ones you've selected, nor can you select a song on your own. You can only navigate forward and back through the list without knowing what you'll hit next.

It is because of this exact deficiency with the Hillbaley Radio (built using Windows Media Services) that I started Flamingo in the first place (at the request of a friend who wanted the ability to "filter out the crap" when listening to my library). So now I'm back to square one. Except that it took much, much longer to build software that doesn't work any better than what Media Services does out of the box.

The issue with WMP 11 is that it wraps the playlist I generate in another playlist. What Flamingo does is generates an XML file in .wpl format and serves it up in a response, relying on WMP to interpret it and do its thing. But rather than simple interpreting the .wpl file as-is, the way WMP 10 does, WMP 11 creates another .wpl file of its own with a single entry called Default. That entry is a reference the temporary .wpl file Flamingo serves up.

The net result is that you are now listening to a playlist that references another playlist, not a playlist that references a bunch of songs.

Most inconvenient.

Sunday, November 05, 2006

So Justice Gray asks (in his own inimitable way), what do you do when inspiration hits and you get the urge to maroon yourself on an island working on the Next Big Thing©?

I've been wrestling with similar questions, on a much smaller scale (and from his description, it pretty much had to be), with Flamingo. The more I think about the features I want to add, the more I think there's commercial potential.

But the more I think about the commercial potential, the more I also think I don't want to deal with it. I talked it over with a good friend of mine ad nauseum asking, "What should I do? Should I add this feature? How should I bill? Should I bring in other coders? Do you want to code for me for free?" And since it's music based, there are also a ton of issues around copyright laws which is definitely something I'd rather avoid (although in the Bahamas, copyright laws are seen more as guidelines).

In my own situation, I'm also dealing with the fact that I already have a full-time+ job working from home plus several other side projects, one of which actually pays. And I live in the Caribbean for Jayzus' sake! What the &*%$ am I doing behind a @#&! computer all day anyway?

So this brought me to an alternate road to success albeit one that will take much longer and one where the benefits are more subtle. In it, I work sporadically, but diligently, on this project and focus more on making it a collaborative project.

I.E. I'll post the code along with some blurb about certain sections and offer it up for discussion. For example, "I used Atlas for this section because..." and "I decided to go with TableAdapters instead of rolling my own Domain layer because..." and so on and so forth.

Since making this decision, I have eased a tremendous amount of personal guilt at not having worked on the project. As in, I don't feel as bad at slighting you, the developer community, as I do Joe Hick in Alabama who may want to use this application to listen to his collection of The Irish Rovers' Greatest Hits online.

The road to success I referred to earlier has a lower payoff  in the event of success but also a lot less risk. The intent is that the idea and the app catch on with the development community which pays off in the form of reputation and potential opportunities in the form of interesting consulting contracts. If it doesn't catch on, I've still advanced my coding skills.

What I like about this is that there is no second-guessing what the general public really wants. And more importantly, I can work on what I want to, when I want to. So while I probably won't become a millionaire overnight, the fact is I'm not doing too badly for myself now anyway.

And besides, I'm a hillbilly who likes his sleep.

Wednesday, October 11, 2006

Finally did an update of Flamingo, my online music player. After reflecting on it, I'm not going to call it an upgrade, just a different-grade. Basically, it's still not releasable but there it is.

New stuff you'll notice:

  • Moved selected music grid beside the search results to make better use of the space. Play button is still too inconspicuous way at the bottom.
  • Added my entire music collection instead of just the WMAs. Only one Air Supply song, folks, so don't be scared. Plenty of other good stuff to be heard.

That's basically it from an end-user perspective. That's a month and a half's work. Of course, you don't see the starts and stops of various research areas but yeah, I'm pretty disappointed in my progress, too.

From an admin perspective, there is the ability to edit the metadata for a particular song which is useful because of the crappy, crappy state the MP3 headers are in. Too bad I'm still working through SQL issues with the authentication piece.

Oh, and be very careful what songs you add to your playlist because you can't remove them again individually.

Much kudos to UltraID3Lib, a .NET library for reading/writing ID3 metadata in MP3 files. It's by Mitch Honnert who, unlike me, clearly doesn't waste his time on things he's not good at, like web design. The library rocks, though and is MUCH easier to use than the Windows Media Player SDK which still uses COM and doesn't hide that fact judging by the various errors that came up while I used it. (Incidentally, COMException 0xc00d0018 could refer to the fact that the account that is reading the files doesn't have permission to them, despite the other "solutions" Google might throw at you.)

Thursday, October 05, 2006

Here's something you may not know about the TextboxWatermark Atlas Control. If you use the normal server-side control as depicted in the samples, the control will clear the watermark text from the textbox before submitting the form if the user hasn't added a value. Which is good. But if you add the TextboxWatermark client-side, it will submit the watermark text as the textbox's value. Which is bad. The rest of this post outlines why this happens so skip it if you don't care.

The TextboxWatermarkExtender class will loop through the Extender and register a little bit of javascript for each watermark control in the extender. One of those pieces is to register an OnSubmit statement which means that the script it's registering will get executed just before the form containing the textbox gets submitted.

The script is just a call to the watermark's onsubmit function in the main javascript file for it. That onsubmit function is pretty basic:

this._onSubmit = function() {
   var e = this.control.element;
   if(_watermarked) {
      // Clear watermark text before page is submitted
      this.clearText(false);
      _clearedForSubmit = true;
   }
}

That is, if the textbox is watermarked, clear the text from it before submitting the page. This is so that you don't submit the watermark text as the textbox's value.

As I mentioned, the code that registers this OnSubmit statement is in the TextboxWatermarkExtender class. This means it is included whenever you use the <atlasToolkit:TextboxWatermarkExtender> control in your aspx page.

It also means that if you are registering your textbox watermark control client-side, you do not get the benefit of this functionality. Because you aren't using the <atlasToolkit:TextboxWatermarkExtender>. you are, I'm guessing, bypassing the Extender class and going straight to the underlying javascript.

You can see this behaviour in action by simply clicking the Search button at the top without putting in a search string. Because I'm adding my watermark client-side, you'll get the search results for the term "Enter a search string". If I were to use the server-side TextboxWatermarkExtender control, I'd get whatever behaviour happens when you search for an empty string in dasBlog.

But of course, I shan't be using the server-side control. My workaround for my blog will be to do nothing. The fix affects only those users who want to search for an empty string for Jayzus' sake. Like I've always said: you can't save everybody.

This came up while working on Flamingo and there, I don't have the luxury of assuming an empty string search will be meaningless. My fix is going to be to use the server-side control because the only reason I had the client-side control in there is to see if I could do it.

If you truly want a solution that you can use client-side, here's a rough draft of something that might work. Create a javascript function that calls the _onsubmit for each watermark object on the form. Doubt you'll be able to do that by iterating through a collection if you have more than one. You'll probably have to call the _onsubmit function for each one manually. Here's how you do it (copied straight from the control's source):

   var o = Sys.Application.findObject('<id of watermark object>'); if(o) { o._onSubmit(); };

At the end of this function, add: return true;

Next, you'll need to wire this function into the form's onsubmit event:

   <form id="form1" runat="server" onsubmit="javascript:return mySubmitFunction( );">

This whole thing is essentially what the extender class does for you. You have other alternatives to registering the submit function. A javascript call to document.forms[0].attachEvent anywhere on the page will probably work, at least in IE. I think the mechanism for attaching events is different in Firefox and Safari. You can also make your own call to Page.ClientScript.RegisterOnSubmitStatement but if you're doing that, you may as well use the server-side control anyway and avoid this mess.

Finally, this doesn't affect all the controls in the Atlas Toolkit. Most of them don't register client scripts in their Extender classes. I had a quick look through a few of them and didn't see any others, in fact. Which makes sense. It'll be necessary anywhere you need to alter the value of a form before submitting it and few of the controls do this.

Wednesday, October 04, 2006

Administrivia first: To those people searching for "hillbilly names" and stumbling across this site, my most humble apologies. Also, I've already abandoned my post-naming convention for fear that they get banned from search engines. And I have a feeling my last post contributed to the trackback spam I'm now encountering...

So I keep waffling back and forth on my preferred AJAX mechanism for Flamingo. The two choices are: roll my own or use Atlas.

There are some advantages to rolling my own. Less research into the technology. I've been AJAX-ing since the days of Microsoft.XMLDocument and I am pretty comfortable with it. I can page and sort fairly easily.

Doing it this way also lends itself to adding the app to live.com or Google's personal portal page or wherever. It seems these portals like it best when you stick with standard HTML and Javascript although I have a feeling they may block anything fancy like XMLHTTP calls to a separate web service.

I can also give the user more visual cues about what's going on. Showing little Processing... messages, clearer error messages, all the things you should do but usually don't.

You also have more control over the content that is passed to and from the server with the XMLHTTP calls but seriously, who really cares about that anyway?

On the other hand is Atlas with its all-powerful UpdatePanel. The compelling argument here? Sweet Jayzus you can build this stuff fast! No mucking around with XPath queries, no javascript coding to determine what page you're on, no futzing with sort directions. ASP.NET has all of this built-in. Ergo, the UpdatePanel has it all built-in.

And with controls like the UpdatePanelAnimation, you can't even argue about the lack of feedback to users while "stuff" is happening in the background.

So for the moment, I'm tilted into the Atlas camp again. This came last night after a couple of hours getting the paging working in the search results page. Faced with the daunting task of now having to wire it all into the selected music list, I decided to flip over to the Atlas version, which didn't have paging yet and see what would be involved in getting that working.

Total elapsed time: 30 minutes including a timeout in the middle to help my daughter sack Eleuthera. For both the search results and the selected music list. And with better paging controls than I had (thanks to what appears to be some upgrades to the paging functionality in .NET 2.0).

This framework is seriously going to rock when the documentation hits.

Finally, a word on LiveWriter. Pretty impressed so far but it has an annoying habit. When you are at the very end of your current post, which you frequently are as you write it, you need to avoid holding down the SHIFT key and selecting text using the keyboard. If you hold SHIFT and press the left or up arrows, you select text normally. But after you've selected text, try pressing the right or down arrows. Nothing happens. Even if you've released the SHIFT key.

In short, if you begin your selection by selecting the final character in your post, you can't de-select anything. My work-around is to start every post with "moo" then begin the post above it.

Thursday, September 14, 2006

Before I get started, Atlas has an official name but I can't be bothered to change the category name so until I do, it's still Atlas on this site.

I'm still working on my music app, tentatively named Flamingo mostly because since I've moved to the Bahamas, I've always wanted to give an app that name. (It's the national bird and the source of a very entertaining albeit somewhat creepy routine at the local zoo). I've gone back to the basics and decided I need to get some features on it before playing around with the cutting edge crap.

One of those tasks is to have a reasonably easy way to update the database periodically as new music is added (and occasionally dropped lest I give the wrong impression). And let me tell you, dealing with metadata for MP3s and WMAs is a hideous process for someone with minor obsessive compulsive disorder.

The first problem comes when key fields are simply not filled in. I'm currently working through a list of approximately one hundred MP3s that have no official title.

That's the easy part. Next problem: People are absolutely horrible at tagging these things. Never mind the filenames_that_include_every_single_piece_of_data_within_them. Worse is when it's just plain wrong. The Guess Who sings Secret Agent Man? Leonard Cohen and Joe Cocker doing a duet on First We Take Manhattan? John Williams wrote the Back to the Future theme? The Rolling Stones doing I Saw Her Standing There?!?! Is one thing to be lazy, it's another to be on &*$%# crack, people!

These are hard things to fix because they don't show up unless you're actually listening to the song. And in most cases, you aren't in any position to actually correct the data.

I'm also extending this problem to one of my main pet peeves about metadata. I hate the fact that all of these fields are atomic. I.E. They take one value and one value only*. Again, my OCD kicks in here and it drives me crazy that I have to file Leon Redbone's and Zooey Deschanel's duet of Baby, It's Cold Outside under *either* R or D in the artist. Plus now I've created a brand new artist in the eyes of WMP: Redbone, Leon & Deschanel, Zooey. Any searches for other tunes by Leon Redbone will not bring up this little gem.

Same goes for albums and genres. The song Let It Be is probably on no less then seventeen different albums when you include soundtracks, greatest hits, compilations, not to mention live recordings. Shouldn't I be able to search for any one of those albums and pull up Let It Be? If a song is on the Bobby Jo's Last Supper soundtrack as well as The Stanton "Family" Reunion's Greatest Hits, a decent music search should reflect that.

The genre field is even more useless as a single-valued field. I haven't the slightest clue what the difference is between R&B, hip hop, urban jazz, funk fusion and progressive adult contemporary (which is a term I just made up but I'm sure has already been used). And people have a tendency to use Soundtrack as a genre unto its own which confuses things further. I can't even begin to try to categorize songs like this one.

So my intention is to not only make these fields multi-valued, but to allow the songs themselves to be tagged. With anything. You think a song is a combination of jazz and boogie? Log 'em both. Fumbling Toward Ecstasy is a good song to make out to? Tag it. You think Paradise By the Dashboard Light would make a good wedding song? Thy voice be heard.

It's coming, campers. The musical revolution will be heard. At least as long as the local electric company can keep the &*$% island powered.

*My experience is limited to how Windows Media Player tags its music. I have no doubt that some other apps have addressed this but I'm leery about dealing with them since the last time I tried, it was with Satan's music player, MusicMatch.

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Copyright © 2010 Kyle Baley. All rights reserved.
 
CATEGORIES
.NET General (18) alt.net (4) altnetconf (9) ASP.NET AJAX (40) ASP.NET MVC (29) Bahamas (1) Bahanet (9) BDD (1) Brownfield (18) Career (9) Castle (1) Code coverage (1) Coding Style (6) Communication (1) Community (18) Conscientious Coding (34) Continuous Integration (11) dasBlog (12) Development (16) DevTeach (4) Domain (2) Environment (4) Estimating (1) Featured (14) Flamingo (10) Games (1) Google App Engine (2) GWT (5) Hardware (6) Java (1) Javascript (7) Linq (2) Livelink (6) Lucene.NET (2) MbUnit (1) Metrics (1) Miscellaneous (24) Mocking (4) NAnt (4) NHibernate (12) NInject (1) Office (3) Office Development (6) Open Rasta (1) Patterns (5) Presenting (13) Professional Development (15) Refactoring (10) ReSharper (11) REST (2) S#arp Architecture (5) Security (3) Software (11) Sundry (18) TDD (19) Tools (21) User Interface (5) Utilities (8) Visual Studio (8) VSTO (1) Web development (12) Windows (3) Working Remotely (16) Workplace (3) Writing (4)
 
LATEST POSTS
 
POPULAR POSTS
 
 
ARCHIVE