jordan.terrell
Just trying to make sense of things...

Type Mocking Dangerous in Static Languages

Monday, 27 August 2007 22:36 by jordan.terrell

Both Ian Cooper and Scott Bellware wrote excellent posts comparing dynamic and static languages, and how type mocking is dangerous when your using a static language (e.g. C#, VB.NET).  Scott said: "Type mocking might save your bacon when you have made poor design decisions along the way..."  I couldn't agree more!  Ian also talked about how dynamic languages leverage Duck Typing to overcome this danger.

Take a look at my friend's Duck Typing library - it's made to be used within a static language.  It too can "save your bacon" when you need to isolate legacy, tightly coupled code that you need to change and test.

You're All Applying the Dependency Inversion Principle

Monday, 27 August 2007 11:12 by jordan.terrell

John has posted a few comments on my previous post about the Dependency Inversion Principle (DIP) debate.  He raised a few questions and the more I thought about it, I felt it warranted a follow up post.

First, when it come to adding support for change ahead of the change, balance is always needed.  No one can future proof their software solutions against change - you'll end up with a ton of infrastructure code that only adds complexity and very little of the value originally intended.  However, change will happen.  Adding support of that at the junction points between tiers/layers is the responsible thing to do in all but the smallest of applications.  Again, balance is always needed - it can be easy to go to far with this.

Next, to answer John's specific questions: "It is the price of the tool that you are worried about?  The commercial support?"  Answer: Yes and no.  The price point is always a concern, as licensing is usually based on the number of computers that it will be installed on.  I appreciate having the right tools for each project, but sometimes the project's budget doesn't include monies for licenses to developer tools - besides Visual Studio.  This is not to say that I'm completely apposed to commercial tools - I'm a large fan of CodeSmith Professional, and I have recommended its use on many projects.    The thing about CodeSmith, however, is that its use doesn't affect the design characteristics of my application.  I can choose to apply the DIP or not, all the while using CodeSmith.  That is the point that I'm getting at - I don't want the selection of a development tool¹ to drive how certain design principles (e.g. Dependency Inversion, Single Responsibility, Open-Closed, Loose Coupling, High Cohesion) are achieved.  John and others have suggested that TypeMock could be used to achieve certain desirable design characteristics.  Take TypeMock away, and I fear in most cases (not all) that you would be left with an non-testable, highly-coupled design.

It has been suggested by those opposed to the DIP in this debate that the only reason developers are using the DIP is because of the use of mocking frameworks in their unit test.  I can see how that perception could easily be arrived at.  When applying the DIP, it provides many testing seams that can be leveraged by a mocking framework.  Let's stop for a second and ask, why is that?  It is because applying the DIP allows one to achieve a measure of loose-coupling.  But with all principles and patterns, a balance is needed.  I do not try to make all class-to-class interactions happen through interfaces; that would be unreasonable.  More often I use it when bridging the connection between tiers/layers of an application (e.g. business layer to data access layer).

You're Applying The Dependency Inversion Principle - You Just Might Not Know It

One of the wonderful things about this field of work is that there are many numerous ways that a principle or pattern can be applied.  There are many ways to arrive at a software solution for a problem - not always right or wrong, but better or worse.  It seems in all of this discussion about using DIP that it somehow became synonymous with using interfaces passed in via constructors, methods, or properties.  This is an incorrect viewpoint.  There is no requirement in the DIP that says interfaces be used, or that it requires the use of constructors, methods, or properties.  Principles can be adhered to many different ways. Dependency Inversion is just that - a principle - not a concrete implementation approach.

Jacob Proffitt said that he would prefer to use providers (abstract factories) instead of DI.  Great - it's still applying the Dependency Inversion Principle!  The Inversion part comes in you use some form of configuration to determine which concrete implementation of the provider will be used at runtime.  You can always implement something into your solution which lets you intercept the request for the provider and return a mocked version - that is if your provider framework allows this.

A Different Approach

I had hinted in a previous post on an approach that I've used in the past based on the Scope<T> MSDN sample.  I whipped² together a sample of this approach for you to take a look at.

First, there is a simple static class that provides simple and clean access to retrieving dependencies (IoC stands for Inversion of Control):

   1:      public static class IoC
   2:      {
   3:          public static T Resolve<T>()
   4:          {
   5:              return Resolve<T>(null);
   6:          }
   7:   
   8:          public static T Resolve<T>(string name)
   9:          {
  10:              return IoCScope.Current.Resolve<T>(name);
  11:          }
  12:   
  13:          public static IoCScope Register<T>(T target)
  14:          {
  15:              return Register<T>(target, null);
  16:          }
  17:   
  18:          public static IoCScope Register<T>(T target, string name)
  19:          {
  20:              return IoCScope.Current.Register<T>(target, name);
  21:          }
  22:      }

 

Next, we have an abstract base class that represents an individual IoCScope, and well as manages the stack of nested IoCScopes.  One nice thing about this implementation is that it allows scopes to be defined for an entire AppDomain, or for just one thread:

   1:      public abstract class IoCScope : IDisposable
   2:      {
   3:          private static Stack<IoCScope> _AppDomainScopes = null;
   4:          
   5:          [ThreadStatic]
   6:          private static Stack<IoCScope> _ThreadScopes = null;
   7:   
   8:          internal static IoCScope Current
   9:          {
  10:              get { return GetCurrentScope(); }
  11:          }
  12:   
  13:          private static IoCScope GetCurrentScope()
  14:          {
  15:              if (_ThreadScopes != null && _ThreadScopes.Count > 0)
  16:                  return _ThreadScopes.Peek();
  17:   
  18:              if (_AppDomainScopes != null && _AppDomainScopes.Count > 0)
  19:                  return _AppDomainScopes.Peek();
  20:   
  21:              return null;
  22:          }
  23:   
  24:          private bool _IsAtAppDomainScope = false;
  25:   
  26:          public IoCScope() : this(false)
  27:          {
  28:          }
  29:   
  30:          public IoCScope(bool appDomainScope)
  31:          {
  32:              _IsAtAppDomainScope = appDomainScope;
  33:   
  34:              Stack<IoCScope> scopeStack = GetScopeStack(_IsAtAppDomainScope);
  35:              scopeStack.Push(this);
  36:          }
  37:   
  38:          private Stack<IoCScope> GetScopeStack(bool isAtAppDomainScope)
  39:          {
  40:              if (isAtAppDomainScope)
  41:                  return _AppDomainScopes ?? (_AppDomainScopes = new Stack<IoCScope>());
  42:              else
  43:                  return _ThreadScopes ?? (_ThreadScopes = new Stack<IoCScope>());
  44:          }
  45:          
  46:          public void Dispose()
  47:          {
  48:              if (_IsAtAppDomainScope)
  49:                  TearDownScope(_AppDomainScopes);
  50:              else
  51:                  TearDownScope(_ThreadScopes);
  52:          }
  53:   
  54:          private void TearDownScope(Stack<IoCScope> scopeStack)
  55:          {
  56:              if (scopeStack.Peek() != this)
  57:                  throw new ApplicationException("IoCScope disposed in wrong order.");
  58:   
  59:              scopeStack.Pop();
  60:          }
  61:          
  62:          public abstract T Resolve<T>(string name);
  63:          protected abstract void RegisterCore<T>(T target, string name);
  64:   
  65:          public IoCScope Register<T>(T target)
  66:          {
  67:              RegisterCore<T>(target, null);
  68:              return this;
  69:          }
  70:   
  71:          public IoCScope Register<T>(T target, string name)
  72:          {
  73:              RegisterCore<T>(target, name);
  74:              return this;
  75:          }
  76:      }

 

IoCScope is an abstract class because it allows you to implement registration and resolution of dependencies using your favorite IoC framework, or to write your own.  Assuming you've created one called MyScope, you can wire up dependencies via code this way:

   1:  using(MyScope scope = new MyScope())
   2:  {
   3:      scope.Register<ISomeService>(new SomeConcreteService());
   4:      ...
   5:  }

 

This registers an instance of SomeConcreteService with the current scope.  In can now be retrieved this way:

   1:  ISomeService svc = IoC.Resolve<ISomeService>();
   2:  svc.DoSomeWork();

 

Within the context of a unit test, you can define a new scope and register mocked instances of services that your component under test depends on.

Conclusion

I guess my overall message is this: You're all applying the DIP, just in different ways, so stop attacking it!  If you dislike the concrete approach that a large group of developers are using, let's talk about that.

 

Nitpicker's Corner

¹I'm not referring to the .NET Framework or 3rd party libraries you would add a reference to - naturally those should have an effect on your design.  I'm speaking of tools used by the developer in the process of writing the software's code.

²So don't expect a feature complete, error-hardened library.  If you choose to use this code in anyway, you accept that I am not responsible for what results, directly or indirectly.  If this sample seems rushed - it was.  If you'd like to have me send you a working Visual Studio 2005 project, request it via a comment on this post and I will send it your way.

There Are No Silver Bullets

Thursday, 23 August 2007 10:48 by jordan.terrell

I had to chuckle when I read one of Ayende's recent blog post on Aspect Oriented Programming.  He ended it with a section called "Nitpicker corner", where he made it clear that Aspect Orientation is not a Silver Bullet.

This is so true. No matter what we've done so far when it comes to software development, there have always been design compromises.  The goal we should all have is to find the right balance in those compromises.  What that right balance is, depends much on each individual project.

There Are No Silver Bullets...

Update: Mats Helander wrote a great post on Silver Bullets.

Dependency Inversion vs Type Mocking: Debate

Monday, 20 August 2007 13:08 by jordan.terrell

In case you haven't noticed, there is a bit of a debate going on over Dependency Inversion and Type Mocking, and the merits of each approach.  Many bloggers have started to weigh in on it; so I thought I would join the fun.

I favor Dependency Inversion. This is not to say that both approaches don't have benefits - they clearly do, and neither side has produced completely ideal results, as was well stated by Aaron here:"...neither sides of the camp is producing Silver Bullets."

Jacob Proffitt (the originator of this discussion) has repeatedly sung TypeMock's praises - and rightly so, as it is a very powerful mocking tool. The fundamental problem I have is this: I refuse to allow my overall application design to be coupled to the availability of a commercial tool or product.  My main goal, and hopefully the goal of all well reasoned developers out there, is to create application where the components are loosely coupled from each other, and the overall design is decoupled from the tools used to make it.  Relying on TypeMock to achieve this seems like an dangerous bet.  I can still achieve this loose coupling without any tools when I apply Dependency Inversion - it may not be the most enjoyable and I normally use tooling; however, I'm not required to, and should I change my tooling in the future it will be likely be less effort to do so.

One approach that I've used in the past is to use ambient service locators, similar to the Scope<T> sample on MSDN.  This allows you to achieve some of the "aesthetic" (for lack of a better word coming to mind) qualities that I think both sides are striving for.  You can still "inject" your dependencies - but you can do so without relying on the traditional approaches (constructors, methods, and properties).  I strongly recommend you take a look at that sample.

Above all, it is the well-established, time-tested principles that we should want to stick to.  Letting a vendor’s product drive your design and how you achieve adherence to those principles may be an unwise approach.

C# Duck Typing library

Sunday, 19 August 2007 23:10 by jordan.terrell
A friend of mine, David Meyer, recently released the latest version of his Duck Typing library for public consumption.  It's written in C# and the source is available.  I'm looking forward to using it when working with "legacy code" to break dependencies.  Anyways, check it out and let him know what you think...
Tags:   , ,
Categories:   .NET
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Powershell 'dir -r' costs 50 watts of electricity

Sunday, 19 August 2007 22:36 by jordan.terrell

I recently received a pretty hefty electric bill, and I wasn't sure on what all that electricity (cash) was being spent on.  Sure, I speculated, but I wanted to make sure - so I purchased P3 International's Kill-A-Watt Electricity Usage Monitor.  It's pretty cool - it will measure Volts, Amps, Watts, Kilowatt Hours over time, among other things.

I immediatly pluged my computers into it, wondering if they were sucking up all of my electricity.  After being relieved that it was not the source of my surge in electrical expense (I'm pretty sure it was my air conditioner), I decided to see how various things I did on my computers changed my electricity consumption.

I was surprised.  When I compiled a simple C# .NET class library in Visual Studio, my electrical consumption jumped 30 watts while it was compiling.  When I did a recursive listing of everthing on my hard drive using Windows PowerShell, it jumped 50 watts of electricity!  I'm thinking this is because the hard drive has to do additional work, and thus consumes more energy - but it's really cool to put some relative hard number to it.

Tags:   , , ,
Categories:   .NET
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed