Hello there! It looks like this might be your first time to my website. You should...
Subscribe to my
RSS feed
Follow me
on Twitter.
Check out
.NET Dev Buzz

The NoSQL Movement, LINQ, and MongoDB - Oh My!

Thursday, April 22, 2010 1:01:01 PM (Pacific Standard Time, UTC-08:00)

Maybe you’ve heard people talking about ditching their SQL Servers and other RDBMS entirely. There is a movement out in the software development world called the "No SQL" movement and it’s taking the web application world by storm.

“Insanity!” you may cry, “for where will people put their data if not in a database? Flat files? Tell me we aren’t going back to flat files.”

No, but in the relational model, something does has to give. The NoSQL movement is about re-evaluating the constraints and scalability of data storage systems in the light of the way modern web applications generate and consume data.

The outcry about flat files above is meant to highlight an assumption developers often have about building data-driven applications: Data goes in the database (SQL Server, Oracle, or MySql). Just maybe, if we are really cutting-edge, we might consider storing our data in the cloud, but the choices generally stop there.

The NoSQL movement asks the question:

“Is the relational database (RDBMS) always the right tool for data storage and data access?”

Starting from an RDBMS is virtually an axiom of software development. However, those of us who are excited about NoSQL believe that relational databases are not always the answer. I think this highlights one of the reasons this NoSQL thing is called a movement. People are realizing they have a choice where they thought they had none.

The converse is, of course, also true. The NoSQL databases are also not always the right choice either. If you look carefully however, you will find that they are a good choice much of the time. Don’t take my word on it. Ask Facebook, Twitter, Digg, SourceForge, WebEx, Reddit and a bunch of other companies here and here that are using NoSQL databases.

This move towards NoSQL is driven by pressure from two angles in the web application world:

  • Ease-of-use and deployment
  • Performance - especially when there are many writers as compared to the number of readers (think Twitter or Facebook).

Choosing NoSQL for Ease-of-Use and Deployment

I cover the programming model in detail as well as introduce the actual database server below. For some vague motivation, let me just give you a quick look at how you define the data model and maintain it.

  1. Define your classes in C# (largely) without regard to putting them in a database. Related classes? Easy - one has a collection of the others.
  2. Create a simple DataContext-like class which exposes each top-level type that is to be stored in the database. This is only a few lines of code per collection (think of this as a table).
  3. Interact with the database using LINQ. This creates the collections (think tables), sets the schema, etc.
  4. Maintain the database and evolve it by maintaining your classes from step 1. *

Why, in the name of all that is right, do we have to model our system twice? Once in the database and once, in parallel, in code? With NoSQL, you have one place to do that - in your C# classes.

* You may have to run a transformation tool if you’re making radical data changes, but that’s true in SQL systems as well.

Choosing NoSQL for Performance

When the number of concurrent clients using your application - and thus your database - is reasonably small (let’s say 500 users as a baseline) RDBMS can work great. But what if that number grows? And if you are writing a web app, you definitely want that number to grow. At 50,000 users, can you still run on a single instance of SQL Server or MySql? How powerful does your hardware have to be to handle that? What about at 500,000 or 5,000,000 users, still good?

I’m sure there are some of you out there thinking, “What a minute now! There are plenty of systems with tons of users built upon relational databases.”

It’s true, there are. But how much expensive hardware and software do these require? How easy is it to leverage *commodity* hardware and free software? A basic SQL Server cluster might run you $100,000 just to get it up and running on decent hardware. Rather than leveraging crazy scaling-up options, the NoSQL databases let you scale-out. They make this possible (dare I say easy?) by dropping the relational aspects of a database. Some NoSQL systems such as MongoDB get even better scalability by loosening some of the durability guarantees – which they backfill somewhat with redundancy (more on MongoDB shortly).

“Ok, ok. So it’s cheaper and simpler,” you say. “How much faster than the finely tune system that is SQL Server 2008 can these open source NoSQL systems be?”

The answer is: MUCH MUCH FASTER. Here’s a simple comparison of running a bunch of concurrent inserts into SQL Server 2008 and MongoDB on the same computer.

Looks like under heavy load, I’d say it’s about 100 times faster. I’m sure there going to be tons of second guessing this graph and so on. Hold your comments please! I’ll be posting a full performance comparison with source code soon. Let me just say that I think the comparison was fair - I’ll back that up in a later post.

NoSQL and a New Programming Model

If we do not have joins and primary / foreign key relationships, how do we associate related data? In NoSQL, there is a way to mimic foreign keys for certain relationships. However the main answer is that you do not disassociate your data in the first place.

I’m sure that you’ve all heard of the object-relational impedance mismatch. A large part of that mismatch comes from the fact that we normalize the data in our database to the extreme and then use joins to reassemble that data. Not only does that cause this so-called impedance mismatch, but those joins can be really slow and they can be the death of any scale-out solution. The key to many of the NoSQL databases’ scalability is that they do not use joins. You simply save large swaths of your data as a single blob (which in MongoDB’s case, is still deeply queriable).

Shortly we’ll look at an example where we build out a disconnected, offline RSS reader that uses MongoDB and LINQ to store its data. But just think about how you might structure your data storage if you could save entire object graphs and still query them? Your "row" might be a Blog object which has an array of BlogEntries which contain the entry text, link, date, etc. Then your *entire* query to pull all the details of a single blog would hit a single “table” in the database. That might look like this query which has one result:

var blog = 
       (from b in ctx.Blogs 
       where b.Id == requestedBlogId 
       select b).FirstOrDefault();

There are no joins or anything like that because you’re saving objects not columns and those objects contain their collections already (e.g. RssEntries). There is an important distinction to make here. These NoSQL databases generally are *not* the same as object databases. They are what are known as document databases. There’s actually a big difference between the two.

Introducing MongoDB

The NoSQL database we are using in this example is MongoDB. This is free, open-source database which runs on Windows, Linux, and Mac OS X systems. You can access it from many platforms including .NET, Ruby, Java, PHP, and so on.

We’ll be using .NET and C# of course. You have several options when choosing how to access MongoDB from .NET but generally that means using LINQ and a light-weight object-mapper on top of MongoDB itself. Note that common terminology might categorize the object mapper that moves objects into and out of the database as an ORM. While that’s OK, there is technically no "R" in this ORM because MongoDB is not relational. Hence I’m calling simply an Object-Mapper (OM).

In MongoDB nomenclature, theses libraries are called drivers. My favorite .NET driver is called NoRM. It’s being actively developed and was created by Karl Seguin, Andrew Theken, Rob Conery, James Avery, and Jason Alexander. You can find NoRM on GitHub and discuss it in its related Google Group.

If you want to learn more about MongoDB you should listen to these Podcast interviews:

Michael Dirolf also has a great book in the works. You can catch a preview of it on Safari Books Online. Here’s the amazon page:

MongoDB: The Definitive Guide.

NoSQL in Action

Let’s write some code. The first step typically in a data-driven application is to spec out the database. Then we’d use LINQ to SQL or Entity Framework to generate the ORM classes. MongoDB is different. MongoDB has no schema or rather its schema is flexible and defined via usage rather than being predefined in the database. So our first step is to define the classes we’d be storing in the DB via NoRM.

We’re going to define 3 classes: Blog, RssEntry, and RssDetail. The Blog object will contain a collection of RssEntry objects. In practice you might just go with the Blog and RssEntry classes. But I wanted to model both the embedded case (Blog + RssEntry) and the loosely defined foreign key style relationship that mimic joins (RssEntry + RssDetail). That way we can demonstrate both use-cases.

Here’s a taste of the Blog class:

public class Blog
{
	public ObjectId _id { get; set; }
	public string Name { get; set; }
	public string Url { get; set; }
	public string RssUrl { get; set; }
	public List<RssEntry> Entries { get; set; }
      // ...
}

Notice that it contains a collection (List<T> really) of RssEntry objects. That’s the relationship supported by nesting. The Blog class just has this collection as part of its data model.

The RssEntry class has the summary info for a blog entry:

public class RssEntry
{
	public ObjectId _id { get; set; }
		
	public Guid UniqueId { get; set; }
	public DateTime PostedDate { get; set; }
	public string Title { get; set; }
	public string RssGuid { get; set; }
}

And the larger data is stored in the RssDetails class (for example the text of the post):

public class RssDetails
{
	public ObjectId _id { get; set; }

	// this is kinda like the foreign key.
	public Guid RssEntryId { get; set; }

	public List<string> Categories { get; set; }
	public string Link { get; set; }
	public string Text { get; set; }
	// ...
}

Let’s see how we insert an entire set of Blog data into the database. We begin by generating the objects (Blog, RssEntry, etc) in memory and then serializing them via NoRM to MongoDB much as you would in LINQ to SQL. The difference is this will actually generate the collections (analogous to tables) if they don’t already exist and it will define the implicit schema to match our objects:

void SaveBlogToMongoDb(
	string rssUrl, XElement root, RssDataContext ctx)
{
	Blog blog = new Blog();
	blog.RssUrl = rssUrl;
	blog.Name = GetBlogName(root);
	blog.Url = GetBlogUrl(root);

	blog.Entries = ParseEntries(root);
	IEnumerable<RssDetails> details 
		= GetDetails(blog.Entries, root);
			
	foreach (RssDetails detail in details)
	{
		ctx.Add(detail);
	}

	ctx.Add(blog);
}

Here we are using a class called RssDataContext which we wrote manually. It is very similar to what LINQ to SQL and Entity Framework use to do the object-relational mapping. Want to do a query? Do you know LINQ? Well then you’re all set:

var results = 
    from b in ctx.Blog 
    where b.Name.Contains( "MongoDB" ) 
    select b;

How do you add a new entry to an existing blog and update it in the database?

void AddEntry(Blog blog, RssEntry entry)
{
	blog.Entries.Add(entry);
	ctx.Save(blog);
}

We leverage the fact that the blog.Entries collection is a List and just add to it. Then save will update the record in the DB.

All this works great and is highly performant. But do be careful as not all the LINQ operations are fully implemented yet in NoRM and some (like join) may never be added because MongoDB doesn’t support it.

To get started, download MongoDB the tools and server here:

http://www.mongodb.org

You unzip the zip file and run the mongod.exe program. Be sure that you have created the C:\data\db folder. It appears at first that you have to run MongoDB in a console window. But you can register it as a Windows Service:

Here’s some helpful advice on installing MongoDB as a Windows Service (there is a small bug you have to work around):

http://www.deltasdevelopers.com/post/Running-MongoDB-as-a-Windows-Service.aspx

There’s also a management console (and I mean "console"):

It’s a little different. You’ll get used to it. The means of interaction with the server is through JavaScript rather than T-SQL and the storage format is a binary form of JSON as you can see.

For a project I’m working on I’ve built a Windows Forms UI that lets me manage the database easily by just adding an object data source and doing some drag-drop magic in Visual Studio. Generally I look down upon that sort of development, but for an admin tool it’s just fine.

Now It’s Your Turn!

Try it out for yourself. Download MongoDB and the NoRM driver and build some apps. You may also want to check out the source code for my demo app:

Download Sample: RssMongoSample-Kennedy.zip

Got feedback? Write a comment or contact me on Twitter where I'm @mkennedy or find me in any of these other ways.

Recommended Reading:

Here are some other blogs on this subject.


 
Tweet this Follow me on Twitter Post this to dotnetshoutout.com Digg this Submit this to Stumbleupon email this post

Building Windows Machines in Amazon EC2

Saturday, January 30, 2010 9:46:04 PM (Pacific Standard Time, UTC-08:00)

In this article I'm going to give you a simple, step-by-step overview of how to create a Windows 2008 server image in Amazon's Elastic Cloud Compute (EC2) infrastructure. Now I must admit I'd rather have found a good tutorial on The Internets or even in a book. Feel free to send me any I missed. My experience is they are either dated or about Linux and so on...

First, briefly why does one care about EC2? Well maybe you are buying into the whole cloud computing story which lets you cheaply out-source your computer hardware for amazingly cheap prices (staring around $0.20 / hour for a dedicated machine). That's a great reason and Microsoft and Google have interesting plays there too.

Personally I just want a simpler way to create virtual machines. We'll have full admin access over remote desktop to our system to install whatever we want. I'm putting Visual Studio 2010 Beta on mine to play around with that software without 'polluting' my real system.

Here we go. If you don't delay I suspect this would take you about 20 minutes from start to login! Subsequent virtual machines are much faster to create and launch because the can be based on pre-configured images.

1. Create an Account

Register for an Amazon Web Services account at http://aws.amazon.com/.

2. Enable EC2 Features

Enable Elastic Compute Cloud for your AWS account at http://aws.amazon.com/ec2/.

3. Launch a New Instance

Use the AWS Management Console to launch and manage your virtual images: http://aws.amazon.com/ec2/home. As the console says, choose "Launch Instance" under the "Getting Started" section. You will be presented with a list of pre-configured images. We'll start with a stock Amazon Windows 2008 server image.

4. Choose a Base Image

Now you'll be presented with a list of pre-configured virtual disk images. This time we'll setup a 64-bit Windows 2008 Server (Data Center Edition). Just choose "select" out of the list below:

5. Use the Request Instances Wizard

Use the Request Instances Wizard to configure the newly created instance which includes configuring the security, choosing an encryption key, opening ports in the firewall, and kicking off the new instance. Below you'll see the encryption key step - be sure to download the key pair as you'll need it for retrieving the administrator password.

6. Launch!

Here's what you can expect for the review screen of the Request Instances Wizard. Press launch and you're almost there.

7. Launching... (AKA Wait 5 Minutes)

After you launch you're instance you'll get a confirmation screen to show you it's being prepared and allow you to configure durable storage and IP addresses (both entirely optional).

8. Back to the Management Console

Now if you choose "View your instances..." you'll see that your instance is being prepared - it has a yellow pending status. This screen doesn't always refresh on its own so use the refresh button in the upper right of the console (rather than your browser's refresh button).

9. Running!

After a few minutes your instance with the yellow icon will turn green and be in the running state. Note that at first this really means booting up so you can't get to it right away. Give it another minute or two...

10. Login Part 1: Getting the Credentials

Now you'll want to login. Of course, the system was created with an administrator account which has a strong password. You'll need to retrieve that password using the "Instance Actions -> Get Windows Admin Password" option.

11. Login Part 2: A Little Hasty

You're probably excited to get this thing running and if you try right away you'll get another message telling you to be patient and try again in a few minutes. Just keep trying.

12. Login Part 3: Using Private Key

Eventual the new system is up and running and you can get the password. The first step here is to pass in your encryption key from the wizard step before.

13. Login Part 4: Administrator Account and Password

Pass in the encryption keys and you'll see the username and password (don't get excited, I already changed the password!).

14. Login Part 5: Finding the Machine Address

When your instance starts, it'll be given an Internet visible DNS name that you can use to connect via Remote Desktop. You'll find it in several places. One of them is highlighted below. Note that this address changes as you start and stop your instance.

15. Connected!

Now just fire up Remote Desktop, use the Administrator account and password from step 13 to log in. Now you have full access to your Windows 2008 machine. You can do with it what you will, install software, start serving web pages, etc.

16. A Word of Caution

If your intent is to run a web server, then let it run. But if you are just using this for your own purposes and don't need it when you're not logged in to the machine, be sure to return to the Management Console and stop the instance. You can alternatively do that by choosing "Shutdown" instead of logging out of your Remote Desktop instance.

I hope you found this walk-through helpful. I just learned most of this myself so I figured I'd blog it and everyone can learn from it.

Cheers!
Michael

Tweet this Follow me on Twitter Post this to dotnetshoutout.com Digg this Submit this to Stumbleupon email this post

Attend My Live, Free TDD Webinar with Llewellyn Falco and Myself at 10am Tomorrow!

Monday, October 26, 2009 3:29:46 PM (Pacific Standard Time, UTC-08:00)

[Update: See the follow-up post here: TDD Invades Space Invaders]

Tuesday, October 27, 2009 at 10am Pacific time Llewellyn Falco and I will be giving a live, unscripted, and no safety-net demonstration of Test Driven Development (TDD) as part of the DevelopMentor webinar series (this particular series is a 3-part series on Agile development).

We already have a bunch of attendees registered. But we have room for as many of you who are interested in agile and TDD. Sign up here:

   http://bit.ly/dm-tdd-m-and-l

In addition to core TDD techniques, you will see how an amazing technique and set of tools designed by Llewellyn called Approval Tests makes writing tests as simple as verifying an image or text file. Tired of writing 50 lines of test code for every 50 lines of production code but you still want the power of TDD? You need to learn more about Approvals and we'll demo that live tomorrow!

I hope to see you all online. Feel free to help me get the word out by tweeting this or shouting it (see icons below).

Cheers, Michael.

Tweet this Follow me on Twitter Post this to dotnetshoutout.com Digg this Submit this to Stumbleupon email this post

Gmail New Mail Notifications for Windows 7

Friday, July 10, 2009 9:44:21 PM (Pacific Standard Time, UTC-08:00)

[Update: Renamed this tool from Gmailer to Gmail 7 due to pre-exiting product name conflicts]

I've been using Windows 7 as my sole operating system since Beta 1 in January. I'm completely loving it and I was pleased to see how many apps worked seamlessly on it. One that didn't and I really miss is Gmail Notifier. No matter how I try, I always get this:

It's insane to me that $130B company can't provide any more than this outdated tool for this job, but I digress...

I've looked and looked for a replacement and they are either no longer online, are crappy applications, and so on. Finally I decided to take matters into my own hands. Introducing a clean, simple, unobtrusive, and free Gmail notification application that works on Windows 7 - Gmail 7:

Gmail 7 simply runs in your tray and plays the Windows new mail sound when mail comes in to your Gmail account.

New Mail:

No New Mail:

That's pretty unobtrusive right? Your account info is encrypted and stored in your user profile and all network access uses SSL.

Download all 41 KB of Gmail 7 here: Gmail7.zip

Requires .NET 2.0 (built into Vista and Windows 7)

Just extract the folder to its final resting place and run it - select "Launch at login" if you want that.

It even comes with some cool ways to view your email by double-clicking the tray icon.

Also thanks goes to Ryan Cook for use of his Gmail C# tools as the basis for part of my project.

Tweet this Follow me on Twitter Post this to dotnetshoutout.com Digg this Submit this to Stumbleupon email this post

Unit Testing Coming to a Workflow Near You

Tuesday, September 30, 2008 7:50:29 AM (Pacific Standard Time, UTC-08:00)
[Update: See the follow up post "Significant Advances in Unit Testing Windows Workflow"]

If you've been working with Windows Workflow, you'll find it has some cool features for orchestration, long running operations, state machines, etc.

However you won't find very much support for Test Driven Development (TDD) or unit testing in general. In fact the architecture that makes Windows Workflow powerful (strict separation of workflow, activities, and the host for example) really gets in the way of unit tests.

There has been some work done on unit testing Windows Workflows. Here's some links:

These are all very creative solutions. But, personally I find all of them more complex than they need to be. So in the near future I'll be putting together some libraries and samples on unit testing Windows Workflow. I think you'll find them far more powerful and at the same time simpler than anything out there.

So until I get that finished, if you have any feedback or considerations on unit testing Windows Workflow I'd love to hear it. If there are other articles I'm missing, please post them in the comments.

I think you're going to like this…



kick it on DotNetKicks.com

Tweet this Follow me on Twitter Post this to dotnetshoutout.com Digg this Submit this to Stumbleupon email this post

Commercial Skip and Instant Replay for Any Computer (Not Just Media Center Anymore)

Monday, June 02, 2008 4:43:35 AM (Pacific Standard Time, UTC-08:00)
Do you watch a lot of video on your computer? I sure do. I download conference talks and interviews. I especially watch a lot of TV recorded by my Windows Media Center PC by copying the video files to my laptop. Media Center is SO much better than TiVo because you can copy / transfer / save video to other places (like your laptop).


A cool Media Center Setup (love it!)

That’s all well and good, except I really miss the ability to skip commercials and pause video via my media center remote control.


Media Center Remote (love this too!)

That’s been a pain to say the least inside Windows Media Player. Well goodbye days of frustrating commercials and TV via the mouse!

Introducing “Minimalist TV Player” (by me!):



It looks like Windows Media Player and has the same basic features for playing video.

But – you can control it like a Media Center TV to skip commercials and replay an action scene (like the crash shown above at the last Indy 500, just jump back 15 seconds to see the replay)!

You can use the keys PageUp to jump back 15 seconds and PageDown to skip commercials (forward 30 seconds). That’s a good start. But, if you have one of these presentation remotes:


Wireless presentation remote
(approx $39)

Then you can use it to control the TV Player like a Media Center Remote! Here’s the control mapping:



Controls for the TV Player

Now you have the same controls as your Media Center PC on any computer that has Windows Media Player installed! How cool is that?

Download the beta 1 version here:  MinimalistTVPlayer (128 KB)

This beta version is fully functional but will expire in 2009. The supported file types depends somewhat on your system. The program will play any video files that your Windows Media Player can play. This usually includes WMV, MPG, AVI, and possibly DVR-MS files from Windows Media Center and DivX if you have the decoder installed.

One final tip: You can associate the application with your video file types and choose “Open With” to directly launch the program from a file:



Just be careful to not set the TV Player as the default program to load your video with unless that’s what you want.

If you this program, be sure to help promote it by kicking it! kick it on DotNetKicks.com

[Update June 5, 2008: I'm working on a much slicker UI which I'll try to get out soon.]

Tweet this Follow me on Twitter Post this to dotnetshoutout.com Digg this Submit this to Stumbleupon email this post

Visual Studio Recent Files Utility Now OpenSource on CodePlex

Monday, March 24, 2008 3:06:27 PM (Pacific Standard Time, UTC-08:00)
If you'v been using my Visual Studio Recent Files Utility, then you may be interested to find out that I just released it as open source on CodePlex here.

    Visual Studio Recent Files Utility on CodePlex

Enjoy!

Tweet this Follow me on Twitter Post this to dotnetshoutout.com Digg this Submit this to Stumbleupon email this post

Big Mailer Utility is Now Open Source on CodePlex

Monday, March 24, 2008 12:28:40 PM (Pacific Standard Time, UTC-08:00)
Hi All,

I recently added my Big Mailer project to CodePlex.

     Big Mailer on CodePlex

You can download the source code among other things.

Enjoy!

Tweet this Follow me on Twitter Post this to dotnetshoutout.com Digg this Submit this to Stumbleupon email this post

Email Something Huge: Introducing the Big Mailer Utility

Monday, March 17, 2008 9:52:54 AM (Pacific Standard Time, UTC-08:00)

I often have to send large files around by email. For example, I had to email a colleague a 10 MB file. It seems a little rude to hit him out of the blue with a 10 MB email. I wanted something cleaner and less intrusive.

So I created a simple utility I called "Big Mailer". I figured I'd blog about it and share it with the world. Feel free to use it as you see fit. This program consists of both a client and server piece that simplifies uploading content to your web site. Then the program gives you a regular web link you can send via email.

Here's a screen shot:

BigMailer

You can download and install it via ClickOnce here:

Install Big Mailer (700 KB)

kick it on DotNetKicks.com

You must have the following to use this program:

  1. .NET 3.5 Framework installed on the client
  2. .NET 3.5 Framework on the server
  3. An ASP.NET web site to host the WCF service

After you install the client, click "Host Service" and you'll get the server side code to drop onto your ASP.NET web site. There is a test web site with instructions in that code.

If you don't have an ASP.NET web site to host the service at you can always use public services like Drop Boks (a great service!) or other file sharing sites. The benefit of this program / service is that you retain control of the files and you can conceivably send more sensitive content.

You can also just use FTP if you have that for your web site, but I hate FTP personally. I don't like fighting the firewall issues and I don't want it running on my servers.

So this program allows you to upload content of unlimited size, without FTP, without sending your files to a third party. Also, it sends everything in 16KB blocks, rather than one giant http message. So you get the benefit of both being able to send huge files (say 1 GB) and you get progress / cancel support.

One feature that's notably lacking is authentication. I'll probably release an update with security built-in. For now, take that into consideration before using it.

Enjoy!

PS - This project is now Open Source and is host on CodePlex.
Tweet this Follow me on Twitter Post this to dotnetshoutout.com Digg this Submit this to Stumbleupon email this post

Visual Studio Tricks Series: #3 Managing the Recent Projects List

Wednesday, September 12, 2007 5:27:40 PM (Pacific Standard Time, UTC-08:00)
Welcome to my third Visual Studio tricks post. This time it's more of a utility, than a tip. I want to talk about managing the recently projects list. If you're like me, then you work with many different projects (especially after I teach a class) and your recent project list becomes polluted with projects you don't care about.

     


In this post, "Recent Projects in Visual Studio 2005", .net DEvHammer discusses how to access the registry to alter that list.

Well, I didn't feel like going to the registry everytime I wanted to clean that list. So I whipped up a simple UI to manage that list (basically manage that registry list).




You're welcome to download this program if it looks useful to you. I decided to publish it via ClickOnce so it will always be up-to-date. If you're using FireFox, you'll need to FFClickOnce add-on to make this work.

    Install Visual Studio Recent Files Utility (approx 200 KB)

kick it on DotNetKicks.com

I hope you enjoy it!

This project is now hosted on CodePlex and is Open Source.
Tweet this Follow me on Twitter Post this to dotnetshoutout.com Digg this Submit this to Stumbleupon email this post


Just a site note: I'm doing my part to rid the world of IE 6. Visit this site with IE 6 and you'll get a shameful message telling you to "Stop Living in the Past".