DI: Instantiating dependencies based on runtime values

Wednesday, 2 May 2012 00:00 UTC

Most of the beginner’s examples of Dependency Injection show very straightforward cases, such as the following:

public interface IDependency
{
    void Method();
}

public class Dependent
{
    private IDependency m_Dependency;

    public Dependent(IDependency dependency)
    {
        m_Dependency = dependency;
    }

    public void DoSomething()
    {
        m_Dependency.Method();
    }
}

This is a typical example of constructor injection, where the Dependent class needs to call some method on the dependency. Constructor Injection keeps everything loosely coupled and it makes us sleep better, nonetheless when we try to implement Dependency Injection in our systems we find out pretty quickly that sometimes we do need to pass arguments to the dependency, be it primitive objects or additional dependencies. Suppose that we have a scenario where multiple implementations of IDependency exist and we want to create an instance based on a run-time argument. In this situation, we cannot use Constructor Injection, since while creating our Dependent instance we still do now know which dependency to instantiate. Intuitively, we want something like this:

public class DependencyOne : IDependency
{
    public void Method()
    {
        Console.WriteLine("DependencyOne.Method() called.");
    }
}

public class DependencyTwo : IDependency
{
    public void Method()
    {
        Console.WriteLine("DependencyTwo.Method() called.");
    }
}

public interface IDependency
{
    void Method();
}

public class Dependent
{
    public void DoSomething(string argument)
    {
        IDependency dependency = // Create dependency using argument
        dependency.Method();
    }
}

Method Injection

The most trivial solution is to use Method Injection and pass the IDependency as an argument.

public class Dependent
{
    public void DoSomething(IDependency dep)
    {
        IDependency dependency = dep;
        dependency.Method();
    }
}

In this case, the dependency is instantiated outside the class based on the string argument that was previously given as an argument to the method, which means that the class can now ignore how this instance is created. Looking at it more closely though, even if the Dependent class is ignorant about the instantiation of the dependency, we know we have to instantiate it somewhere. How would the client code using the Dependent class look like? Well, we would have to instantiate the dependency at runtime based on the string argument…sounds familiar?

In the best case scenario, the client class is in the Composition Root of the application and is allowed to resolve the dependency directly, though in non-trivial applications this is rarely the case. Since we moved the creation of the dependency one step higher, the burden of instantiation is on the client and should it not be the Composition Root than we are left with the same issue; it follows that Method Injection is not an adequate solution for most cases when it comes to resolve dependencies at runtime.

The limitedness of this solution brought us a bit closer to solving the problem though: what if we delegate the instantiation to some place in the Composition Root? That would allow us to instantiate the dependency in a point where we can access all implementations of the interface and compose it either manually or using our container of choice.

We could create a class and give it the responsibility to instantiate our dependencies based on the runtime arguments that they need. From this description, our class looks like a factory…

Factory

The idea behind this approach is to delegate the creation of the object to a factory and let the factory instantiate the dependency. We could let the Dependent class be ignorant about the use of a factory and let its method require an IDependency instance, but what’s the point? The client code has to instantiate a factory anyway, so let’s give the factory as an argument to the method in the dependent class itself. Better yet, we can inject the factory in the constructor, effectively coming back to a Constructor Injection solution.

public interface IDependencyFactory
{
    IDependency Create(string argument);
}

public class Dependent
{
    private  IDependencyFactory m_DependencyFactory;

    public Dependent(IDependencyFactory factory)
    {
        m_DependencyFactory = factory;
    }

    public void DoSomething(string argument)
    {
        IDependency dependency = factory.Create(argument);
        dependency.Method();
    }
}

As a result, we are not relying on the dependency itself, but on the factory: this solution is flexible and leaves room to decide how to effectively implement the factory itself.

One could argue that we increased the complexity of our API: now we publish an additional abstraction, the factory, and our clients have to account for that. On the other hand, implementing a factory for this behavior means applying the Single Responsibility Principle and I see nothing wrong with it, independently from DI.


Learning Ruby with TDD

Wednesday, 9 November 2011 00:00 UTC
I was starting to have a look at the book from Kent Beck (Test Driven Development: by Example), shame on me that I didn't yet find the time to read it, and I thought I could use the occasion to get the basics of Ruby. Caution: I have no previous knowledge of Ruby. On one side, this means that I will write particularly bad code in ruby. On the other side, it is a nice opportunity to put TDD to good use and see if I can refactor some code as soon as I learn the "Ruby way" of doing stuff. The idea is to go through the basic Money example from Kent's book and just use Ruby for the code. Luckily Ruby comes with a basic unit testing framework, and I think it's more than enough to start. I will be using Textmate to code and run the tests and ruby 1.8.6 on OS X.

Let's get started!

A short summary for those who didn't read Kent's book: we are trying to define a class which should be able to perform different operations on money with different currencies. We're going test first, so the first piece of code we are going to write in Ruby is a unit test! Yay! To be able to access the unit testing classes we are going to need the file test/unit.rb. There are two ways to do this: one is the require method, and the other is the include method. To keep it short, we are going to use the require method because it just runs the file, but for a deeper analysis of the differences you can have a look here. Just a tip: include is a "false friend" for developers with C/C++/C# backgrounds, so be careful. Now that we've got that out of the way, we can write the test class with the first test (multiplication). I chose to write both tests and code in a file named Money.rb. Let's see how that looks in Ruby:
require 'test/unit'

class MoneyTests < Test::Unit::TestCase
  def test_multiplication
    five = Dollar.new(5)
    five.times(2)
    assert_equal(10, five.amount)
  end
end
Ok that looks pretty easy: we defined a class MoneyTests which inherits from Test::Unit::TestCase. The class has a method test_multiplication that checks if a dollar multiplied by 2 is 10 dollars. Let's run the tests simply by going into a terminal and writing "ruby Money.rb", or from inside TextMate which I personally prefer (shortcut CMD + R), if only for the red/green colors jumping to my face at a key press.
Loaded suite /Users/filippo/Documents/RubyTests/Money
Started
E
Finished in 0.00031 seconds.

  1) Error:
test_multiplication(MoneyTests):
NameError: uninitialized constant MoneyTests::Dollar
method test_multiplication in Money.rb at line 7

1 tests, 0 assertions, 0 failures, 1 errors
  It looks like we have some coding to do! We have to define a Dollar class with a constructor taking an integer as input, define a method times and a field amount. I'll give it a try:
class Dollar
  attr_reader :amount

  def initialize(amount)
    @amount = amount
  end

  def times(multiplicator)
  end
end
The class is defined but the test is failing with the following error:
Loaded suite /Users/filippo/Documents/RubyTests/Money
Started
F
Finished in 0.007974 seconds.

  1) Failure:
test_multiplication:18
<10> expected but was
<5>.

1 tests, 1 assertions, 1 failures, 0 errors
It turns out we have to implement the times method (no way!). I feel pretty comfortable in implementing an integer multiplication, so I'll go on and just implement a basic behavior without needing to fake the result:
def times(multiplier)
  @amount = amount * multiplier
end
We can re-run the tests now and we get our first successful assert in ruby!
Loaded suite /Users/filippo/Documents/RubyTests/Money
Started
.
Finished in 0.000259 seconds.

1 tests, 1 assertions, 0 failures, 0 errors
Comforting, isn't it? Please take a moment to enjoy the cozy illusion of a passing test. Back? Great, because now it's time to change our multiplication API. What? Already? Yes, why, it's software we're writing, silly. In fact, as Kent notes in the book, it is a bit awkward to work with a field. Besides, wouldn't it be nice to be able to write the following?
def test_multiplication
  five = Dollar.new(5)
  five.times(2)
  assert_equal(10, five.amount)
  five.times(3)
  assert_equal(15, five.amount)
end
Why do we wantto do that? The devil lies in the details...look at how we named the variable containing the value of 5 dollars: five. We see it as immutable. We want it to be immutable. This in turn means that we have to return a new Dollar as the result of the multiplication, which would make the test code look like this:
def test_multiplication
  five = Dollar.new(5)
  product = five.times(2)
  assert_equal(10, product.amount)
  product = five.times(3)
  assert_equal(15, product.amount)
end
Does it look good enough? We modified the test so that the API is a bit more predictable and easy to use, and we have to change the times method to return a new Dollar instance like this:
def times(multiplier)
  Dollar.new(self.amount * multiplier)
end
Running the test we see that it is green again! The next step is testing for equality:
def test_equality
 assert(Dollar.new(5) == Dollar.new(5))
end
As a side note, it looks like there are three equality operators in Ruby: "==", "eql?" and "equal?". According to this page the equivalent for the Java equals() is the == operator, so I've decided to use it in the test. As the test is failing, we override the implementation of the == operator to return a comparison of the amount fields in the corresponding classes:
def ==(dol)
  self.amount == dol.amount
end
This implementation makes our test pass, which in turn should make us happy! Now that we implemented the equality operator, we can make our multiplication test even more clear:
def test_multiplication
  five = Dollar.new(5)
  product = five.times(2)
  assert_equal(Dollar.new(10), product)
  product = five.times(3)
  assert_equal(Dollar.new(15), product)
end
Actually, we can also get rid of product:
def test_multiplication
  five = Dollar.new(5)
  assert_equal(Dollar.new(10), five.times(2))
  assert_equal(Dollar.new(15), five.times(3))
end
At this point it is time to get rid of the amount field, because it is only used by Dollar. This one is a bit more tricky and it took me a bit longer to port to Ruby. The new Dollar class looks like this:
class Dollar
  def initialize(amount)
    @amount = amount
  end

  def times(multiplier)
    Dollar.new(@amount * multiplier)
  end

  def ==(anotherDollar)
    @amount == anotherDollar.instance_variable_get("@amount")
  end
end
amount is now an instance variable, and to access the instance variable from the other dollar object anotherDollar I had to use the method instance_variable_get. So I learned that you can actually access any instance variable of an object with this method. Nifty!

Continuous Integration with Hudson

Wednesday, 6 October 2010 00:00 UTC
After hours spent painfully integrating existing projects in our automatic build automation process at work, it is a good time to spend a couple of words on the topic of continuous integration. A good time for me to help keeping my sanity in this jungle of project dependencies that the compiler is resolving without any issues on the original developer’s machine, but fails miserably on a neutral environment, yet at the same time an opportunity to revisit the good old principles of continuous integration.

What’s continuous integration, anyway?

From Wikipedia:
In software engineering, continuous integration (CI) implements continuous processes of applying quality control - small pieces of effort, applied frequently. Continuous integration aims to improve the quality of software, and to reduce the time taken to deliver it, by replacing the traditional practice of applying quality control after completing all development.
The concept of continuous integration has its roots in the Extreme Programming community and is based on several practices describing the key objectives to strive for in order to achieve continuous integration:
  1. Maintain a single source repository
  2. Automate the build
  3. Make your build self-testing
  4. Everyone commits to mainline every day
  5. Every commit should build the mainline on an integration machine
  6. Keep the build fast
  7. Test in a clone of the production environment
  8. Make it easy for anyone to get the latest executable
  9. Everyone can see what’s happening
  10. Automate deployment
While most of them are self explanatory, lots of different tools are available nowadays to help a team implement these practices. Quite obviously, you won’t find a tool that magically materializes automated tests out of thin air for your existing code base: however, one can come a long way in just a matter of minutes, having a build automation software set up in just a couple of clicks. I will tell you how we did that for our .NET projects using Hudson.

Meet Hudson the butler

Hudson is an open-source continuous integration server that can be set up in no time. It butlercan be easily tested thanks to Java Web Start at the following address: https://hudson.dev.java.net/hudson.jnlp. Once the Java Web Start application has launched, point your browser to http://localhost:8080 and you will be promptly presented with Hudson’s dashboard. hudson_dashboard That’s it! We can already start configuring our first job: as an example, we are going to build Prism. As noted in the source code page, Prism’s SVN URL for the latest release is https://prism.svn.codeplex.com/svn/V4: we will just write it down for the moment. Let’s click on New Job and select Build a free-style software project from the next page. Don’t forget to set a name for the project before clicking ok, I just named it (drum roll…) Prism.  We are now welcomed by the job configuration page! We are going to focus on the Source Code Management section: as a start, we want to check out the project from the SVN repository. In order to do so, click on Subversion and enter the repository URL that we previously found: SVN At this point, we can Save our configuration and click on Build Now in the project’s page. Notice the Workspace item in the menu and on the dashboard of the project: there you will see the whole project structure once Prism has finished downloading. BuildNow While Prism is downloading you can actually have a look at Prism’s website if you don’t know what you’re downloading.
Prism (formerly known as Composite Application Guidance for WPF and Silverlight) provides guidance and a re-usable code library for building modular, flexible WPF and Silverlight applications.
When the download is complete, we can go on with the project configuration. If we look under the Build section of the configuration page and try to add a build step clicking on the relative button, we find a couple of options: since this is a .NET project and we have no batch file set up to build it for us, we have to use MSBuild, that is not supported out of the box. But fear not! There’s a plugin for that. It is sufficient to go back to Hudson’s dashboard, to click on Manage Hudson and finally Manage Plugins. From here you can easily install the MSBuild plugin and restart Hudson. One thing is left to do: set the local MSBuild path, so that Hudson can find it. Under Manage Hudson –> Configure System you will find a section named MSBuild Builder where you can add the path to your local MSBuild.exe, for instance C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe. We’re finally ready to build! We’re going to add a build step in the Prism project configuration page, choose our local MSBuild version we just configured and point it to the solution to build. build Just a word of caution: if you are using an express edition of visual studio you’re not going to be able to compile the MSTest projects inside the solution. In this case, just remove these projects from the solution. Once the configuration has been saved you can again click on Build Now and Hudson will try to build our Prism solution. In case the build failed, you’ll notice that your last build in the Build History area has a red icon instead of a blue one. What I suggest you to do is to go to that build’s page and click on Console Output which will show you exactly what went wrong.

That’s fine, but where’s the “continuous” part of it?

We have laid the foundations of our continuous integration process. You probably already noticed that the configuration page contains lots of different settings, for example the Build Triggers one. Here you can specify when the build should be started. Every night at 4 AM? Every hour but only if changes in the repository were detected? You name it. How are you supposed to notice if the build breaks? For starters, there’s a built in support for email notifications: that means you can send an email to the developers who broke the build, so that they can notice right away when something is not right. Alternatively you could notify your Nabaztag or publish the results to a Google Calendar or whatever. The possibilities are almost endless, thanks to Hudson’s extensibility. The list of plugins is indeed impressive: you can keep track of your unit test results having them published on your project’s page as a graph, you can track the TODOs in your source code, publish your project artifacts so that they are ready for release and much more. All you have to do is configure everything once: it will take some time, especially for legacy projects needing some dependency cleanup, nevertheless it is a pain you have to suffer just one time. And this is of course only the tip of the iceberg; from here on, the roads of continuous integration are open to you.

Page 3 of 4