Aug 3 2010

"Anonymous Types" in Ruby

Category: Software DevelopmentJeff @ 06:42

Readers of this blog know that I'm an avid C# .NET developer.  However, one can hardly survive long in this business without learning multiple approaches to programming.  In the C# world, we have functional programming (lambda expressions, action and func delegates, etc. ), declarative programming (config files, fluent interfaces, etc.), procedural programming (gasp!) and elements of object oriented programming (though C# isn't a "pure" object oriented language - it's actually "class oriented", but that's a discussion for another blog post).

In an effort to expand my horizons even further, I've started investigating the world of Ruby.  Ruby is a dynamically typed, interpreted language.  Many people have heard of Ruby in the context of Ruby on Rails (RoR) though the language can be used for general purpose programming as well.

As a first project, I wanted to see just how "dynamic" Ruby really is.  Well, it's not quite what I expected.  I had this idea that objects in Ruby would work something like an ExpandoObject in C# 4.0.  While Ruby objects don't work like this out of the box, it didn't take a lot of effort to accomplish this behavior in Ruby.

  1. class Anonymous
  2. def initialize(hash)
  3. hash.each do |key,value|
  4. self.class.class_eval do
  5. define_method("#{key}=") do |value|
  6. instance_variable_set("@#{key}", value)
  7. end
  8. define_method(key) do
  9. instance_variable_get("@#{key}")
  10. end
  11. end
  12. send("#{key}=", value)
  13. end
  14. end
  15. end
  16.  
  17. d = Anonymous.new :foo => 'bar'
  18. puts d.foo
  19. d.foo = 'baz'
  20. puts d.foo

Let's walk through what is going on here in an effort to better understand how Ruby works.  On line 1, I am declaring a class called "Anonymous" that I want to behave sort of like Anonymous types in .NET (but with both getter and setter behavior).  Line 2 declares a constructor for this class which receives one parameter called "hash".  Skip down to line 21 and you can see a few things going on.  First, a variable "d" is declared, and I am creating a new instance of the Anonymous type by calling Anonymous.new.  The really interesting code happens at the end of this line where I am defining a ruby hash.  Equivalent C# code would look something like this:

var d = new { foo = 'bar' };

However, in C# you run into a couple of issues.  First, you cannot change the value of "foo" anymore.  Second, you can't return this anonymous type from a method. Well, you could, but the caller would have no idea what the return type would be and couldn't work with your object without some nasty reflection.  Such concerns don't even in matter in Ruby, however, since it is a dynamic, interpreted language.

On line 22 I'm simply writing the value of "foo" out to the console (puts in Ruby is the .NET equivalent of System.Console.WriteLine()).  Notice that on line 23 I am able to change the value of "foo" from 'bar' to 'baz'.  The class Anonymous has been constructed to automatically create a getter and setter for "foo".  In declaring another Anonymous type, I can specify a different hash and attach a whole new set of properties to my object.  In just 19 lines of code, I was able to create a class with the behavior of an Anonymous .NET type, but including setter behavior.

In a future post, I'll dive deeper into the implementation details of the Anonymous class.  For now, I'll stop there and just ponder ways to use this functionality.  I'm impressed with Ruby's ability to allow the expression of complex behavior with minimal code.

(thanks to emilio for helping me get this Ruby stuff working!)

Tags: , , , ,

Apr 17 2010

Dependency Injection Flavors - The Good, The Bad and the Ugly

Category: Software DevelopmentJeff @ 08:19

UPDATE: check out the code at http://codepaste.net/t4z78p if the stuff below isn't formatted well for your browser.

using System;
using NUnit.Framework;

namespace DependencyInjectionApproaches
{    
    /// <summary>
    /// There are multiple flavors of Dependency Injection - 
    /// 
    /// 1) Constructor injection - dependencies are passed in as constructor parameters
    /// 2) Setter injection - dependencies are passed in to setter methods
    /// 3) Service locator - dependencies are registered with a static gateway which serves up 
    ///     the dependencies (not really dependency *injection* per se, but let's not be sticklers)
    /// 4) PMDI - Poor Man's Dependency Injection (more to come on this one later)
    /// 
    /// I've found that Setter Injection (SI) and Service Locator (SL) have an inherent problem 
    /// because they hide dependencies.  If my class-under-test uses SI or SL, then I often have 
    /// to inspect the source of the class to understand which dependencies must be wired up for 
    /// testing the class.  With Constructor Injection (CI), all of the dependencies are right 
    /// there in the constructor.  There are quite a few other issues related to this matter
    /// which I will discuss below in the context of demonstrating each flavor of dependency 
    /// injection.
    /// 
    /// I've defined an interface "IService" and with multiple implementations.  Each concrete
    /// implementation depends on "ILogger". This dependency is resolved in different ways
    /// for each concrete implementation of IService.
    /// </summary>
    [TestFixture]
    public class DependencyInjectionSpecs
    {
        [Test]
        public void using_constructor_injection()
        {
            var testLogger = new TestLogger(); // Moq would be better, but trying to focus on DI here
            var sut = new ConstructorDependentService(testLogger); 
            
            sut.DoWork();
                        
            testLogger.LastMessage().ShouldEqual("ConstructorDependentService did work");
            
            // (*) when I build the System-Under-Test (sut) see how I can't even call the constructor 
            // without the dependency?  that's good.
            // also notice that I'm only testing my System-Under-Test (SUT) in its interaction with
            // a single dependency.  Good unit tests usually look like this. They only test one class 
            // in its interactions with one abstraction of a dependency.
        }
        
        [Test]
        public void forgetting_to_wire_up_dependency_in_setter()
        {
            var sut = new SetterDependentService();
            
            sut.DoWork(); // throws a NullReferenceException        
            
            // Oops.  I'm able to create my SUT, but I can't execute the DoWork method on it.  Why not?
        }
        
        [Test]
        public void remembering_to_wire_up_dependency_in_setter()
        {
            var testLogger = new TestLogger();            
            var sut = new SetterDependentService();
            sut.Logger = testLogger; // Note this extra requirement for the test to work (*)
            
            sut.DoWork(); 
            
            testLogger.LastMessage().ShouldEqual("SetterDependentService did work");
            
            // (*) That's better than the last test, but more work than the first one.
            // I can still make this test pass, but there's an extra setup cost.  Note that the 
            // dependency is hard to see immediately (we missed it in the previous test).
            // With constructor injection I get a compliation error if I don't set up the dependency.  
            // With setter injection, the missed dependency is not discovered until run time.  Oops.
        }
        
        [Test]
        public void forgetting_to_wire_up_dependency_in_service_locator()
        {
            var sut = new ServiceLocatorDependentService(); // Crud! - KeyNotFoundException (*)
            
            // (*) The test throws immediately due to lack of service registration. Even worse, the 
            // dependency is completely opaque. At least with setter injection I could inspect the 
            // SUT with intellisense, now I'm totally hosed.  I have to look at the implementation 
            // of ServiceLocatorDependentService to figure out how to test it (or if I can at all).
        }
        
        [Test]
        public void remembering_to_wire_up_dependency_in_service_locator()
        {
            var testLogger = new TestLogger();
            ServiceLocator.Configure<ILogger>(() => testLogger); // additional complexity - see below (*)
            var sut = new ServiceLocatorDependentService();
            
            sut.DoWork(); 
            
            testLogger.LastMessage().ShouldEqual("ServiceLocatorDependentService did work");
                        
            // (*)  I'm no longer testing my System-Under-Test in isolation with its dependency, 
            // but I'm also testing my ability to register and resolve dependencies with my Service Locator.
            // This gets worse when my SUT has multiple dependencies which must be resolved from the 
            // Service Locator.
        }        
        
        // PMDI = "Poor Man's Dependency Injection"
        // PMDI may seem like a nice compromise.  You get a default parameterless constructor which uses
        // default implementations of dependencies.  The trouble arises when you want to modify the 
        // constructor of one of *those* dependencies.  What if DefaultLogger changes to require a 
        // constructor parameter? Now changes ripple to all classes that use PMDI with DefaultLogger.
        
        [Test]
        public void PMDI_is_tempting_you()
        {
            var sut = new PoorMansDependencyInjectedService();
            
            sut.DoWork();                
            
            // There is nothing to assert, nothing I can test.  I could visually check my console output, 
            // but doesn't that defeat the whole purpose of an *automated* unit test?
        }
        
        [Test]
        public void PMDI_wants_you_to_come_to_the_dark_side()
        {
            var testLogger = new TestLogger();
            var sut = new PoorMansDependencyInjectedService(testLogger);
            
            sut.DoWork();
                
            testLogger.LastMessage().ShouldEqual("PoorMansDependencyInjectedService did work");

            // yes, it passes.  and with the *same* number of lines as the first example with 
            // constructor injection.  but consider the costs.
            
            // 1) DefaultLogger might change to have constructor arguments (rippling problems, 
            //    but at least caught at compile time)
            // 2) DefaultLogger might change to have setter injected dependencies (now you're 
            //    really hosed! runtime exception!)
            // 3) this is really an SRP violation (Single Responsibility Principle).  Your class 
            //    is not only doing its own job, but is also tasked with determining its appropriate 
            //    defaults.  I suggest you centralize this code in an application bootstrapper and 
            //    find a better way to resolve default implementations (incidendally, StructureMap
            //     has some spectacular abilities in this regard).

            // my last word on PMDI:
            // it seems to me that PMDI is just an attempt to avoid teaching Dependency Injection 
            // to people. I think we're better off showing people all the options and explaining 
            // the pros/cons of each. Perhaps even PMDI has it's place, but it shouldn't just be 
            // the knee-jerk default.  For a shining example of the abuse of PMDI, check out 
            // many of the samples Microsoft released for ASP.NET MVC 1
        }
                    
        #region test support code not relevant to the discussion of dependency injection
        
        [TearDown]
        public void after_each_test_method_executes()
        {
            // make sure we have a clean service locator after each test run.
            // otherwise a registered service from a previous test run can affect
            // the results of other tests, causing false positives or false failures
            // (both really, really bad).
            ServiceLocator.Reset(); 
        }        
        
        #endregion        
    }    
    
    #region more test support code not relevant to the discussion of dependency injection

    public static class SpecificationExtensions
    {
        public static void ShouldEqual(this string actual, string expected)
        {
            Assert.AreEqual(expected, actual);
        }
        
        // check out the NUnit.Specs project for a library of fluent wrappers
        // for NUnit assertions:
        // http://nunitspecs.codeplex.com/
        // I think they are much more clear and concise than the out-of-the-box
        // assertion syntax of NUnit.
    }
    

    #endregion        

    public interface ILogger
    {
        void Log(string message);
    }
    
    public class DefaultLogger : ILogger
    {
        public void Log(string message)
        {
            Console.WriteLine(message);
        }
    }
    
    /// <summary>
    /// Yes!!! - I would much rather use a Mocking framework like Moq, but I
    /// don't want to muddy the waters since the focus here is on learning
    /// dependency injection.  
    /// </summary>
    public class TestLogger : ILogger
    {
        string _lastMessage;
        
        public void Log(string message)
        {
            _lastMessage = message;
        }
        
        public string LastMessage()
        {
            return _lastMessage;
        }
    }
    
    /// <summary>
    /// I hate xml comments, but in this context they just might help you.  :)
    /// </summary>
    public interface IService
    {
        void DoWork();
    }
    
    /// <summary>
    /// Implementation of IService using Constructor Injection
    /// </summary>
    public class ConstructorDependentService : IService
    {
        ILogger _logger;
        
        public ConstructorDependentService(ILogger logger)
        {
            _logger = logger;
        }
        
        public void DoWork()
        {
            _logger.Log("ConstructorDependentService did work");
        }
    }

    /// <summary>
    /// Implementation of IService using Setter Injection
    /// </summary>
    public class SetterDependentService : IService
    {
        ILogger _logger;
        
        public SetterDependentService() { }
        
        public ILogger Logger { internal get { return _logger; } set { _logger = value; } }
        
        public void DoWork()
        {
            _logger.Log("SetterDependentService did work");
        }
    }
    
    /// <summary>
    /// Implementation of IService using Service Locator
    /// </summary>
    public class ServiceLocatorDependentService : IService
    {
        ILogger _logger;
        
        public ServiceLocatorDependentService()
        {        
            _logger = ServiceLocator.GetInstance<ILogger>();
        }        
        
        public void DoWork()
        {
            _logger.Log("ServiceLocatorDependentService did work");
        }
    }
    
    /// <summary>
    /// Bonus! Implementation of IService using Poor Man's Dependency Injection
    /// </summary>
    public class PoorMansDependencyInjectedService : IService
    {
        ILogger _logger;
        
        public PoorMansDependencyInjectedService() : this(new DefaultLogger())    { }
        
        public PoorMansDependencyInjectedService(ILogger logger)
        {
            _logger = logger;
        }
        
        public void DoWork()
        {
            _logger.Log("PoorMansDependencyInjectedService did work");
        }
    }
    
    /// <summary>
    /// NOTE: this is a terrible implementation of a service locator the only purpose of which
    /// is to demonstrate the pitfalls of overreliance on ServiceLocation in your classes.
    /// *IF* you are going to do service location, you're better off using the implementation
    /// from a Dependency Injection framework (like StructureMap's "ObjectFactory").
    /// You might also consider the CommonServiceLocator project:
    /// http://commonservicelocator.codeplex.com/
    /// In general, however, I recommend you steer clear of service locator until you grok
    /// dependency injection enough that you are using constructor injection the majority of 
    /// the time.
    /// </summary>    
    public static class ServiceLocator
    {
        static readonly System.Collections.Generic.Dictionary<Type, Func<object>> Configuration
            = new System.Collections.Generic.Dictionary<Type, Func<object>>();
        
        public static void Configure<TService>(Func<TService> factory)
        {
            Configuration.Add(typeof(TService), () => factory());
        }
        
        public static TService GetInstance<TService>()
        {
            var factory = Configuration[typeof(TService)];
            return (TService)factory();
        }
        
        public static void Reset()
        {
            Configuration.Clear();
        }
    }
}

Tags: , , , ,

Dec 2 2008

ToFormattedList Extension Method

Category: Software Developmentemilioc @ 05:54

Forgive me if this incorrect, but I believe the ToFormattedList() IEnumerable extension method was part of the early ASP.NET MVC previews.  If you’ve used the method then you are aware of its usefulness.  You pass in a format string (ex. “<li>{0}</li>”) and you get back a string of all the objects that were in your IEnumerable individually formatted ("very nice" -Borat).  This is perfect if all the objects in your IEnumerable have an acceptable ToString() method. What if you are working with POCOs or business objects and you would like to use a property instead of an objects ToString() value?  This is exactly the scenario that prompted me to create a ToFormattedList() extension method for IEnumerable<T>.  

To satisfy this new requirement I needed to add a new parameter.  My version of ToFormattedList() takes a Func<T, string> parameter to access the appropriate property (we need the func, we gotta have that func).  Below is the simple code that makes this work and example of its use.

Code

    public static string ToFormattedList<T>(this IEnumerable<T> list, string format, Func<T, string> func) {
        var s = "";

        foreach (T item in list) {
            s += string.Format(format, func.Invoke(item));
        }

        return s;
    }

Usage

    var output = companies.ToFormattedList("<li>{0}</li>", c => c.Name);

Tags: , ,