Saturday, August 16, 2008

Boba Fett, Greedo, and StructureMap

"Austin, Texas. You will never find a more wretched hive of scum and villainy. We must be cautious."

These words were uttered by an inhabitant of the the wastelands around Austin.  Shrouded in mystery, most people think he's nothing more than a crazy old wizard.  He keeps to himself mostly, occasionally seen associating with the lowest sort of riff-raff, and forever spouting mumbo-jumbo about some bizarre religion he follows.  But there are those who know his true identity, that he is in fact the legendary Jedi Obi-Wan Kejeremy.

Ahhh, forget it.  I just can't keep up the extended metaphor anymore.  In keeping with my last post, I was going to go into some long, labored Star-Warsy exposition about Jeremy's new padawans, Chad and Josh, and the work they've done with him on a secret weapon called StructureMap.  But it's late, I'm tired, and I want to finish this post tonight, so let's just skip right to the point, mmmmm-kay?  I took the code I wrote for the last post and used StructureMap to decouple things a bit further after reading through Chad's articles (here and here) as well as a bunch of stuff Jeremy has written about StructureMap.  Since there are still those among us who are fashionably late to the .NET 3.5 party, I used StructureMap 2.0.  I also thought a bit more about the design and changed some things around after looking at Josh's code (and, let's be honest, outright stealing some of his code).  And no, I didn't write tests for this stuff, and yes, I know that makes me a lazy jerk.  See sentence four in this paragraph.

So here's how the Program class changed:

   1: class Program
   2: {
   3:     private static void Main(string[] args)
   4:     {
   5:         Configure();
   6:  
   7:         IAppEngine appEngine = ObjectFactory.GetInstance<IAppEngine>();
   8:         appEngine.Run();
   9:     }
  10:  
  11:     private static void Configure()
  12:     {
  13:         StructureMapConfiguration.UseDefaultStructureMapConfigFile = false;
  14:         StructureMapConfiguration.BuildInstancesOf<IAppEngine>().TheDefaultIsConcreteType<AppEngine>();
  15:         StructureMapConfiguration.BuildInstancesOf<IOutputDisplay>().TheDefaultIsConcreteType<ConsoleOutputDisplay>();
  16:         StructureMapConfiguration.BuildInstancesOf<IStuffStrategy>().TheDefaultIsConcreteType<LitterOfKittens>();
  17:         StructureMapConfiguration.BuildInstancesOf<IDrinkingEstablishment>()
  18:             .TheDefaultIs(
  19:             Registry.Instance<IDrinkingEstablishment>()
  20:                 .UsingConcreteType<Cantina>()
  21:                 .WithProperty("name").EqualTo("Mos Eisley Cantina")
  22:             );
  23:     }
  24: }

I love it!  That Configure() method allowed me to break almost every dependency.  The only time I'm actually using the new keyword is in the AppEngine (lines 15 and 22), and if I weren't falling asleep I could probably figure out a way to get rid of it there too.

   1: public class AppEngine : IAppEngine
   2: {
   3:     private IDrinkingEstablishment _drinkingEstablishment;
   4:     private IOutputDisplay _outputDisplay;
   5:  
   6:     public AppEngine(IDrinkingEstablishment drinkingEstablishment, IOutputDisplay outputDisplay)
   7:     {
   8:         _drinkingEstablishment = drinkingEstablishment;
   9:         _outputDisplay = outputDisplay;
  10:     }
  11:  
  12:     public void Run()
  13:     {
  14:         GetANewPatron("Boba Fett");
  15:         _drinkingEstablishment.SetStuffStrategy(200, new ConfusionOfWeasels());
  16:         GetANewPatron("Greedo");
  17:         _outputDisplay.Get();
  18:     }
  19:  
  20:     private void GetANewPatron(string name)
  21:     {
  22:         IPatron patron = new BountyHunter(name);
  23:         _drinkingEstablishment.WelcomePatron(patron);
  24:         foreach (IStuff thing in patron.Basket)
  25:             _outputDisplay.Put(thing.DoSomething(patron));
  26:     }
  27: }

So, without further adieu, you can download my little experiment and peruse it to your heart's content if you just click right here.  Laugh at it all you want to.  I'll be asleep.

Share this post :

1 comment:

Chad Myers said...

I tried posting a comment, earlier, but it got snarfed somehow.

Cool stuff, Dale. Thanks!

You might consider moving all your SMAp config stuff into a separate class file that derives from StructureMap's "Registry".

Also, consider using the preferred "ForRequestedType<T>" syntax vs. BuildInstancesOf<T> syntax.