A Culture of Microcomponents

Imagine that you are given the opportunity to rewrite (or upgrade with extreme prejudice) one of your older .NET 2.0 (or 1.1) projects using .NET 3.5.  You wrote it, so you have intimate knowledge of the current architecture, what parts smell, what works well.  You know what custom components you wrote to solve various problems, etc.  You also have a ton of lessons learned.  Now you get to do again, only this time you have more advanced, sharper tools at your disposal.

I went through this process recently and came up with no shortage of 3rd party libraries I wanted to use for the new version:

This list is nothing to sneeze at, and it's just what I could remember... in fact it's probably a bit longer.  This tends to scare people, as it is a lot of stuff to learn.  What the heck are these things?  Where did they come from?  Do I need it?  How do I learn it?  Why did you include this?

That's a great question.  Why do I want to use all of these things? 

I firmly believe in leveraging the work of others, and writing code that is expressive and easy to maintain.  Some of these projects exist solely to make working with another item from the list a lot easier.  NHibernate is a great example.  I loves me some NHibernate, but writing XML mapping files by hand isn't what I'd call a fun time.  Fluent NHibernate makes this so much nicer.  The last thing I want to do is reinvent the wheel.

I don't think I'm alone here.  Most projects I come across have a similar attitude regarding re-using rather than re-inventing.  Most come with a dozen or so additional libraries so that it can function.  I recently asked on twitter how many 3rd party libraries folks are using.  The average result was about 5, but some were as high as 12.

The bottom line for me is:  The value I get from leveraging 3rd party tools is greater than the psychic weight that they cause.  But others may not agree with me.

What about the Ruby community?  Don't they have this problem?  Absolutely.  But I don't think they would classify it as a problem, and I'd tend to agree.  Say you're writing a ruby app and you somehow want to integrate flickr with twitter and paypal.

> gem install flickr
> gem install twitter
> gem install paypal

...Wait what?  That's it?  Yep.  Rubygems is a thing of beauty.  It lowers the barrier to installing 3rd party plugins and libraries.  Rails plugins has a similar concept.  Need to rate one of your models? 

script/install plugin acts_as_rateable
Want to use jQuery instead of prototype/scriptaculous?  simply run
script/install plugin jrails

These techniques allow you to add small pieces of functionality to existing applications with relative ease.  You don't have to open a web browser & search for the tool.  You don't have to download & extract it somewhere.  And you don't need to copy it into your project tree.  Everything is done with a single command.

It seems as if every concept and service has their own gem or rails plugin.  Rails applications today can be built rather simply by composing tiny pieces of functionality written by other people. 

So why can't we do this in .NET?  Well in short, we can... but it requires a culture shift.  For starters, in .NET we generally check in all of our dependencies into source control, so that we can always guarantee that each developer has all of the required tools (and the specific versions of such tools).  With ruby gems, each gem is installed into a common location, which is consistent across all machines (actually it is configurable, but the point is it's a global directory).  To use one of the gems installed on your machine, you simply do this:

require 'hpricot'

It knows to load up that library from a central location.  When this application is deployed to another environment, the same thing occurs.  Gems are installed via the same commands as on the dev machines.

Back at ALT.NET Seattle 2009 I convened a session to discuss revitalizing one of the many gems-for-.NET projects.  We identified several efforts along similar lines as gems:

  • ngems
  • cogs
  • nu
  • horn
  • Machine.PartStore

Out of this discussion, a few folks decided to start fresh with a new project (affectionately called rocks), and toy with getting rubygems to work with IronRuby and wrapping it all in our own command line interface.  Not much has been done on this except a quick spike, but I think the idea is promising.

I believe that if something like this comes up in the .NET community it will lead to a shift in how we think about dependencies, components, and overall re-use of small pieces of code to build larger applications. 

What do you think?

#1 Chad Myers avatar
Chad Myers
5.01.2009
1:31 PM

Yes, sir. Thank you, I'll take 3 :)

Where do we start?


#2 Morten Lyhr avatar
Morten Lyhr
5.01.2009
1:46 PM

I see the culture of micro-components as direct opposites of the SharePoint/MS CRM/CMS where every thing is glued together.


#3 Tom Opgenorth avatar
Tom Opgenorth
5.01.2009
2:19 PM

I agree with what you say - I have a folder on an external HDD with zip files of a lot of the stuff I use.

The problem I always seem to run into is political, the Not-Invented-Here syndrome, or it's brother Not-From-Microsoft myopia. Case in point: I suggest Monorail to a client, they light the torches and get the pitchforks. Suggest ASP.NET MVC, and at least they listen before releasing the hounds.


#4 sam avatar
sam
5.01.2009
2:21 PM

great post. I'm actually at this very point for a special side project. Great post! And I agree that .net needs something like this, but I disagree that we'd like to mimic the command-line aspects of ruby gems. Rather institute the same process with hooks into VisualStudio, why re-invent the wheel right?

One aspect that the new mvc templates have taken from RoR is the ability to create the controller/view stack with a few simple clicks and this is the path that I'd like to see .net rocks take. Just please, if a capistrano look-alike appears...learn the pain points and avoid these in .net. :-)


#5 Scott avatar
Scott
5.01.2009
2:29 PM

Re: local gems repository - Isn't that what the GAC is supposed to provide?

One of the big reasons that gems is easy/successful is because ruby projects don't suffer under the "tyranny" of VS project files.


#6 Peter avatar
Peter
5.01.2009
2:30 PM

Ironically SharePoint does do something similar with their Solution/Feature framework, which in an ideal world, packages up all the customizations you could possibly need, and deploys them on all servers at a scheduled time. There's even a Feature to add jQuery (see smarttools.codeplex.com/.../View.aspx ).

But I'm not disagreeing with Morten, it does seem glued together.


#7 Simone avatar
Simone
5.01.2009
2:35 PM

You forgot xVal :)

I do believe that a big mind shift is needed: devs now expect Microsoft to give them all they need to build their apps. This is changing, but in all the talks I gave about ASP.NET MVC the most frequent question was: "Why do I need to use xyz to do abc? Why is it not part of the framework?"

The saddest thing is that the founder and most prominent voice of the Italian .NET UG still says that ASP.NET MVC is not "mature" because to accomplish client-side validation you have to use xVal.


#8 benscheirman avatar
benscheirman
5.01.2009
2:38 PM

You're right, I did! I would actually say you "get" to use xVal. Who says Microsoft needs to write all of our frameworks & libraries?


#9 Darrell Mozingo avatar
Darrell Mozingo
5.01.2009
3:32 PM

"With ruby gems, each gem is installed into a common location, which is consistent across all machines..."

You'll have to forgive my ignorance having never used Ruby in earnest, but what happens if you only want to upgrade one or two projects with a new assembly? Wouldn't keeping them in a global store require all projects to update at the same time, potentially introducing breaking changes at inopportune times?


#10 paul cowan avatar
paul cowan
5.01.2009
6:03 PM

I have been one of the main contributors to horn and I think we have got reasonably far down the road to success.

I think our approach is unique in that we are dealing with source code. Ruby gems is a bad analogy for .net because we are dealing with compiled binaries in .net and rubygems is about code diles.

The only way to truly resolve dependencies is to build from the source.

We desperately need contributors. Can I make an impassioned plea for some talented .net devs to help us out,

We are very close to building our stack.

Join the horn user group.

Your software platform needs you.

We are very close to making significant progress


#11 Shey avatar
Shey
5.02.2009
4:41 AM

Great idea! Downloading and configuring each component is a *huge* barrier to entry; in my experience, every time you have to setup a component you leave yourself vulnerable to the Not-From-Microsoft syndrome which Tom alluded to.


#12 benscheirman avatar
benscheirman
5.02.2009
10:21 AM

@Scott: that's a good point, but some of the friction in getting and installing makes it less useful. Also I'm talking about things that you can't put in the gac like nant.exe or jquery.js


#13 benscheirman avatar
benscheirman
5.02.2009
10:23 AM

@Darrell: yes and no. You can always upgrade but have other projects request specific versions.


#14 Robz avatar
Robz
5.02.2009
7:05 PM

I love me most of those 3rd Party Frameworks too!

Where would we be without log4net, FluentNhibernate and NHibernate? Oh yeah, writing more code... :D

A couple more:

Rhino.Mocks

FileHelpers

BDDDoc

UppercuT

SolutionFactory ;)


#15 Sergio Pereira avatar
Sergio Pereira
5.03.2009
6:19 PM

I think we definitely need this sort of gem-like functionality for .NET components, I'm just not 100% convinced RubyGems are the model we should be looking at. Ruby libraries are loaded different than .NET ones (referenced and loaded) and the language allows you to include the gems directory in the loading process at runtime.

I keep thinking things like yum/apt/rpm are closer to what we need. Gems could work too, especially if we figure out a way to add "gem references" in a .NET project and make the compiler know where to find the binaries.


#16 Nick Parker avatar
Nick Parker
5.03.2009
7:30 PM

Ben,

David Laribee and I started working on ngems back near the end of 2007 (on Google Code hosting) and moved the project to Assembla and renamed it to nu. We've had other contributors along the way but the parties involved got busy with other things and it has become stagnant. Here are the links to the original and current source code sites. Let me know if you have any interest in these, feel free to contact me:

code.google.com/.../ngems http://www.assembla.com/spaces/dashboard/index/nubular


#17 Arnis L. avatar
Arnis L.
8.12.2009
2:02 AM

When i was toying with RoR, thought exactly the same to myself - only i wasn't sure would or would not this be possible for .NET.