private override

18Nov/090

Don’t Single Me out!

In my few days of being a developer, I’ve heard and seen lots of talk about Singletons.  Things like

Singletons are teh suck.  Don’t use them.  EVAR.

to

Singleton’s saved my life and marriage!

In fact, I might’ve been the person that said both of these… gasp!

I never like to speak in absolutes, so I’ll say it this way (see what I did there?)… if you’re striving to implement a singleton, you’re probably wrong.  For all you guys that are right, I guess you’re right, and you can leave now, I guess.  This might help you out.

I was reading a blog from Mr. Dependency where he was talking about statics and basically what amounts to global state, and how thatultimate-geeks-multi-tool-hammer binds you into globally available, global data, which usually (always?) turns into anarchy.

How do we always get ourselves into this mess if we know it’s bad in the first place?  Well, some of us (those who are now zombocomming, from above) don’t know it’s bad in the first place, and the rest of us probably do it because it’s easy to implement, and we understand it.  Long story short, we can do the singleton implementation in our sleep, so we pull out the singleton hammer, and smack the nail.  It always goes in a little sideways, but at least it goes in.

Maybe we should be using a different hammer?

What I’d like to do now, is propose to split singleton in two.  I think there are two distinct responsibilities that the current thought of ‘singleton’ introduces. It:

  • Manages Session Scoping/Lifecycle/Lifestyle (albeit, poorly, only one strategy is available)
  • Disables the ability to create more

When I talk about this out loud, I call the two approaches the singleton implementation pattern, and singleton lifecycle.

What I am a fan of, is the singleton lifecycle.  You create one of those objects, and use it throughout the application.  You don’t get messy and allow global access to it all over the place (which necessarily happens when you have global state).  You intentionally inject it to collaborators, and  intentionally don’t inject it to non-collaborators (don’t just hand this guy out willy-nilly, he’s important).

So naturally, the naysayers ask/demand:

How do you manage that there is a public constructor on this class!?  Dev’s are going to be new’ing this thing up all over the place!

I say:

False.  Use a DI tool and let it manage it for you.  Or establish a convention with your team, and enforce it through social contracts.

Both of these approaches allow your scope lifecycle turn into whatever you want at any time, in case you decide global isn’t what you really want.  It can be application session scoped, or some other scope, test scoped, or whatever you want… incredibly flexible.

If you go with the DI tool approach, instead of tying yourself to a particular scope, you can now have any scope you want, by changing a configuration parameter.  Delaying decisions until the latest responsible moment… seems like I’ve heard that one before.

12Mar/091

Dependency Injection and Service Location

I was having a discussion with a colleague the other day about DI and Service Location in the context of the question (posed by a third person):

Which DI container/framework should I choose?

His answer:

None; just roll your own and use simple Service Location

I'm not meaning to ruffle any feathers, but I couldn't come up with a good case on the spot, but as I've thought about it some more, I completely disagree, respectfully (at least for the reasons that I choose to use a DI container).

What are the reasons I use to decide whether or not to use a DI container?

  • Reduce Coupling
  • Testability
  • Declarative Configuration
  • Testability
  • Rapid Development

Using a simple service locator pattern, with a hand-rolled instantiation mechanism, can get you the first two, but not the last (unless you spend many many hours on your hand-rolled solution, which would most likely turn out just like one of the already existing containers).  If you don't care about declarative configuration, does that mean the using a container vs not using a container is roughly the same?  No.

There are two other major benefits that I get from using a container that are not in the list above, but I feel are important, and help testability.

  • Published/declared dependencies
  • Autowiring

Published dependencies vs implicit dependencies

Below is an illustration of two constructors.  The first uses published dependencies, and the latter uses implicit.

public MovieLister( IMovieFinder finder )

{

    // DI style

    _finder = finder;

}

 

public MovieLister()

{

    // service locator style

    _finder = ServiceLocator.Resolve<IMovieFinder>("CsvMovieFinder", "movies.txt");

}

 

The first is more easily testable and usable, because you know your dependencies up front (published by the constructor signature).  Whereas you don't know unless you look at the implementation which services are needed with the implicit dependency example.  Additionally, with this example, you're tied to the implementation of the service locator, and also to using the CsvMovieFinder key (I suppose this key could be in AppConfig or some other configuration mechanism, so it could actually be configurable).

I agree it can be just as simple to inject mocks into your service locator for testing the implicit example, but I'd rather not have to think about it.  Publishing those dependencies up front makes it easier for the client consuming that object to use and extend, because then the client developer knows exactly what is expected.

Autowiring

When dependencies are published, it allows the container to use autowiring to build up your application instance.  This may sound like hand-waving magic to those of you that haven't seen it in action, but it truly is one of the best features that comes from using a DI container.

The following example shows a simple example of how autowiring can work.

public class Program

{

    private IContainer _container;

 

    public Program()

    {

        // configure container

        _container = new Container();

        _container.Register<MovieLister>();

        _container.Register<IMovieFinder, CsvMovieFinder>("movies.txt");

    }

 

    public void Run()

    {

        // uses autowiring to inject CsvMovieFinder

        // into MovieLister

        MovieLister lister = _container.Resolve<MovieLister>();

 

        lister.List( Console.Out );

    }

}

 

The container builds up a dependency graph for the requested object, and walks it bottom-up, supplying each parent with the required dependencies.  In this example, the container sees the published dependency that the MovieLister has on the IMovieFinder, and automatically instantiates the IMovieFinder it knows about and injects it as it is created.  This case is somewhat trivial since the graph is only one or two levels deep, but I know you've ran into code before where this would be useful.

Service Location with a DI container

Sometimes it is useful to use the service locator pattern, I'm certainly not refuting that.  Its definitely possible, and is usually the easiest way to get introduced to using a DI container actually.  In fact, the last example uses the container in exactly that fashion when pulling the MovieLister out of the container.  The program is using the container as the service location facility.  The key being though, that we're leveraging the robustness of the container to autowire and instantiate anything else it needs rather than requiring each dependency to wire themselves up.

It is also worth mentioning that Microsoft has released a common container interface called the CommonServiceLocator, for helping framework developers abstract their container choice away from client developers, so they can pick whichever container (or roll their own) that they want.

Hopefully this clears something up for someone, and doesn't just muddy the waters.

11Feb/092

Dealing with Dependencies – A Presentation on DI and IoC

I gave a presentation recently at my company (www.sep.com) on the basics of DI and IoC.  On how they are different, how they relate, why you should care, and how you can get started.

Here is the slide deck: http://jonfuller.googlecode.com/svn/trunk/presentations/dependencies/Dealing%20with%20dependencies.pptx

There isn't anything here that is new or groundbreaking, but I feel like its a decent intro with a couple decent examples.  Let me know what you think!