Entries
RSS 2.0

Comments
RSS 2.0

ALT.NET Podcast on IoC and DI

I’m a few days late on this, but I participated in the latest episode of the ALT.NET Podcast. In it, Brad Wilson, Mike Moore, and I talk about inversion of control and dependency injection and how it can help you write better software. I had a great time recording it, and I thought it was a good conversation. Major thanks to Mike for organizing the podcast and inviting me to participate, and to Brad for not showing me up big time and making me look like a complete dunce. ;)

Part two is coming soon now available, where we get into other fun things like inversion of control with dynamic languages, and Microsoft’s relationship with the open source community.

Applying IoC to Brownfield Projects

There’s a good discussion going on in the ALT.NET mailing list about the steps of learning to use a dependency injection framework. The topic got the cylinders firing in my brain about a question I’ve been asked before: how can inversion of control be applied to brownfield projects — that is, legacy applications that have been around forever?

First off, understand that inversion of control is something that needs to be designed into your software. It’s much more difficult to come in after the software has already been designed and try to inject inversion of control into the mix. That being said, it’s certainly possible. Following Chad Myers’ lead of creating a list of phases, here’s my suggestion for the process:

  1. Create a service locator backed by your favorite DI framework — which, of course, should be Ninject! ;) In my last post, I explained how to accomplish this with Ninject, but the same idea can be applied to other DI frameworks just as easily.
  2. Find all instances of the problem of creation — where dependencies are being created from within the implementation of the types that depend on them — and replace them with calls to your service locator.
  3. Remove all lifecycle concerns (artifacts of instantiation behaviors) from your types. For example, if you’ve got the Singleton pattern with the traditional MyService.Instance construct, get rid of it and start using the framework instead.
  4. Increase your application’s cohesion. Find classes that violate the Single Responsibility Principle and break them into multiple classes to get better separation of concerns.
  5. Decrease your application’s coupling. Within reason, follow the Interface Segregation Principle and replace any interactions between concrete types with interfaces.
  6. Gradually shift from your reliance on the service locator to the dependency injection framework itself. Typically, this can be done by exposing the dependencies of a type on the type’s constructor, and using the framework to resolve and inject them. This will decouple your types from your service locator, and unlock some of the more powerful features of the framework.

The most important thing to remember is that dependency injection is a mindset. You have to let it alter the way you write your code to be successful at using it. Also, as you start to rely on it as a pattern, you will see it start to spread and “infect” your codebase. As long as it still feels natural to work with, this is a good thing, because it means you’re achieving success in making your application more flexible. Trust the framework and let it help you do your job!

Playing Nice With Service Locators

When I introduce dependency injection to developers, I often receive the complaint that it’s not significantly better than the service locator pattern. The main disadvantage of a service locator is that you’re required to couple all of the services in your application to the service locator in order for them to resolve their dependencies. By using a DI framework instead, you can keep your services very loosely-coupled.

However, there are some advantages of the service locator pattern. In particular, it’s much easier to implement hybrid activation — when some of the values in a constructor are provided by the consuming code, and some are provided by the framework. Hybrid activation is common in situations where you don’t need (or want) your DI framework to control the instantiation behavior of the type, but you still want to be able to resolve dependencies that are required for the instance.

In Ninject, hybrid activation is possible through the use of context parameters, which allow you to provide values for specific constructor arguments when you request the instance. However, context parameters can only be used for active requests — that is, calls to the kernel’s Get() method. If you often call Get() on the kernel, you’re using it as a service locator anyway.

The reality is, there’s nothing inherently wrong with using a service locator — when used in the right way, it can greatly simplify your code. I don’t think that service locator and dependency injection are mutually exclusive; in fact, I’ve found that it can actually be very effective when used in conjunction with a dependency injection framework like Ninject.

For example, let’s say you have an EventWatcher service that listens for a named event on an IMessageBroker, reads event information from the message, and triggers a specified callback. The implementation of such a service might look like this:


public class EventWatcher<T> {
  public EventWatcher(string eventName, Action<T> callback, IMessageBroker messageBroker) {
    //...
  }
}

You can’t easily activate a service like this using the Ninject kernel (at least without using context parameters), since the first two constructor arguments have to be supplied from the consuming code, and only the third is actually a dependency that should be activated via the kernel.

However, let’s introduce a simple service locator, which just delegates activation requests to a Ninject kernel:


public static class ServiceLocator {
  private static IKernel _kernel;
  public static void Initialize(IKernel kernel) {
    _kernel = kernel;
  }
  public static T Get<T>() {
    return _kernel.Get<T>();
  }
  public static object Get(Type type) {
    return _kernel.Get(type);
  }
}

Then, when we initially create our kernel, we just have to pass it to the Initialize() method of the ServiceLocator:


public static class Program {
  public static void Main() {
    using (var kernel = new StandardKernel(...)) {
      ServiceLocator.Initialize(kernel);
      //...
    }
  }
}

Using the service locator, we can alter our implementation of EventWatcher to make it easy to pass in the event name and callback method arguments, while still leaving it flexible enough to swap out the implementation of IMessageBroker. This is particularly useful for testability, since you can easily swap in a mock implementation of IMessageBroker in your tests.


public class EventWatcher<T> {
  public EventWatcher(string eventName, Action<T> callback)
    : this(eventName, callback, ServiceLocator.Get<IMessageBroker>())
  { }
  [Inject]
  public EventWatcher(string eventName, Action<T> callback, IMessageBroker messageBroker) {
    //…
  }
}

As you can see, if the more limited constructor is called, the EventWatcher asks the ServiceLocator to resolve the instance that should be used. Notice also that I’ve still kept the [Inject] attribute on the second constructor, in case you want to activate the type using the kernel and context variables.

While this is a useful technique in limited use, it’s important to be careful how much you rely on it. Remember that every time you use a service locator instead of dependency injection, you’re coupling your type to the service locator — and since it’s a static method call, it’s coupled just about as tightly as you can get. Again, though, taken in small doses, this technique can actually simplify your code and make it much more flexible.

Ninject Featured in InfoQ

Rob Bazinet, an editor for InfoQ, was kind enough to interview me about Ninject for the 1.0 release! Check out the article if you’d like to read more about the ideas behind Ninject and what went into its creation.

Ninject 1.0 Goes Gold

It’s always great to watch an idea mature from its first conception. About 18 months ago I began work on the first version of Ninject, which was then called Titan. It’s gone through a lot of iterations and all sorts of changes along the way, but today I’m happy to announce that Ninject 1.0 has officially gone gold and is available for download.

I’ve put in a lot of effort over the past couple of months to make Ninject multi-platform. One of the original goals of the Ninject project was to create a light enough framework that dependency injection was viable anywhere you could run a CLR. I’m proud to say that 1.0 supports the following platforms:

  • .NET Framework 2.0, 3.0 and 3.5
  • .NET Compact Framework 2.0 and 3.5 (Ninject.Core and Ninject.Conditions)
  • Silverlight 2.0 beta 2 (Ninject.Core, Ninject.Conditions, and all shipping extensions)

The same codebase is used for all supported platforms, with certain features turned off when the platform doesn’t support them. Unless I’m mistaken, Ninject is the first dependency injection framework to officially support the .NET Compact Framework or Silverlight, and this is no small feat. Kudos to Mike Eaton for kicking me in the right direction by encouraging me to provide Silverlight support. :)

It’s rare that open source software reaches a full version 1.0, instead preferring to remain beta-0.999 or release candidate 63. I’m not sure why that is; maybe open source developers are just too aware of the deficiencies of their software and are afraid to claim that the product production-ready. I’ve personally used Ninject in production systems for over a year now, and by now I’m very confident that it’s ready for prime time.

I’ve also taken the opportunity to re-launch the Ninject website. At the Cleveland Day of .NET, Brian Prince mentioned that he was frustrated that many open source project websites don’t contain any information about what the product is or does. I’ve tried to fix that with the new design, introducing some value propositions that I think explain how Ninject can help you write sleek, well-designed software that can stand the test of time.

So, what are some of the features of Ninject 1.0?

  • Constructor, property, method, and field injection
  • Instantiation behaviors (singleton, one-per-thread, one-per-request)
  • Fluent interface for declaring type bindings
  • Contextual bindings, where the selection of which type to instantiate can be delayed until activation
  • Support for instance scope and deterministic disposal
  • Fully pluggable, modular design: each kernel component can be easily replaced to alter the framework’s behavior
  • Lightweight interceptor support (aspect-oriented programming)
  • Integrations with other popular frameworks

I’d like to thank all of the companies and individuals that have contributed to the project, whether it’s been bug reports, patches, or software licenses. Please take some time to look at the products of the companies listed on the sponsors page.

I’d also like to dedicate this release to my wife Nicole, who has been understanding enough to put up with me hammering away at a keyboard for hours on end late at night. (She also helped me put together the cool products available in the Ninject store!) I love you sweetie. :)

Anyhow, grab the software, check out the manual, join in on the discussion, and by all means, buy some swag! :)

New Host, New Design

If you’re seeing this post, welcome to the new site! I’ve moved my blog to a shiny new virtual private server on Slicehost, and tweaked the design a bit. The three-column layout of the old design was a little bit cluttered, so I’m hoping the new simplified layout is a little easier on the eyes. Let me know what you think, and if you run into any problems.

Attributes? We Don’t Need No Stinkin’ Attributes

Ninject will reach 1.0 later this month. As the project has gained traction, I’ve received a common complaint concerning the use of the [Inject] attribute to decorate dependencies. Ninject was originally designed to match my own tastes, and I don’t personally mind the attribute in this case. The common argument against attributes is that it hurts the readability of your code, but I would suggest that in this case it actually improves its readability by making it more declarative. At a minimum, it says “this value comes from somewhere special,” so even if there are other developers working with your codebase that don’t entirely understand dependency injection, the use of [Inject] is enough to get them asking questions.

However, while I would consider Ninject to be opinionated software, I also want to make sure it’s useful to people with differing tastes, as long as I can do so without sacrificing the common case. To that end, I’ve been working to make it easier to dodge the attribute requirement. There are actually four different ways of avoiding the use of [Inject], depending on the level of control you want over your codebase. Note that this article describes features available in the subverison trunk, which will become version 1.0 with very few modifications, but most are not available in RC1. However, I do my utmost to make sure that the trunk build of Ninject remains stable, and I am currently using it in production applications without trouble.

1. Use Automatic Constructor Injection

The first, and easiest way to avoid the attribute is to use automatic constructor injection. If a type only has a single constructor, Ninject will attempt to inject it regardless of whether or not it is decorated with an [Inject] attribute. Therefore, if you’re willing to accept the limitation of only using constructor injection, you can avoid using [Inject] anywhere in your code.

2. Use a Custom Injection Attribute

If it’s not the requirement of the attribute that bothers you, but the fact that it means you have to have a dependency on Ninject.Core throughout your code, you can customize the attribute that Ninject will look for to inject dependencies. This is done via KernelOptions. For example:


public class MyInjectAttribute : Attribute {}

public static class Program {
  public static void Main() {
    var options = new KernelOptions { InjectAttributeType = typeof(MyInjectAttribute) };
    var kernel = new StandardKernel(options, ...);
  }
}

Now, rather than decorating your dependencies with [Inject], you instead use [MyInject], and avoid the dependency on Ninject.Core. If you use optional dependencies, you can override the [Optional] attribute in this way as well.

3. Use the Auto-Wiring Extension

A recent addition to Ninject is Ninject.Extensions.AutoWiring, which provides a way to inject dependencies without ever needing to decorate them with attributes. Instead, which dependencies that are injected will be based on what bindings you register with the kernel. When a type is activated, Ninject will do the following things:

  1. It will find a constructor on the type whose parameters all have types for which bindings are registered. If there are multiple constructors available, it will select the one with the most parameters with bindings defined.
  2. Similar logic will be applied to methods — if the type defines methods whose parameters all have valid bindings defined, dependencies will be resolved for the arguments and the methods will be called.
  3. Finally, all properties and fields will be considered as well. If their types have bindings defined, they will be injected.

To use auto-wiring, you just need to load the AutoWiringModule into your kernel, and the extension re-wires the kernel components as necessary. A couple caveats:

  1. Auto-wiring does not work with implicit self-binding, so you will have to explicitly register self-bindings for all of your types to get Ninject to resolve them.
  2. As you might imagine, auto-wiring will slow down activation. However, it’s unlikely you’ll notice a change in performance unless you’re activating millions of instances via Ninject — and if you are, you might want to rethink your design. :)
4. Roll Your Own Heuristics

Ninject is designed to be ultra-customizable. The core is built around a collection of kernel components, which the kernel orchestrates in order to activate types, resolve dependencies, and do all the fun stuff that you’ve come to love from Ninject. My latest work leading up to 1.0 has been to adjust the model of Ninject to favor composition more over inheritance (a good design principle in general, by the way). Ninject ships with a collection of standard implementations of components, but you are free to remove them and replace them with your own custom implementations. Since most of the components are very granular, this is easier than it may seem… all you need to do is create a type that implements one of the components’ interfaces, and connect them to your kernel.

There are four components, called selection heuristics, that can be replaced to customize which members are chosen for injection. As you might imagine, they are:

  1. IConstructorHeuristic
  2. IPropertyHeuristic
  3. IMethodHeuristic
  4. IFieldHeuristic

You may replace any or all of these to take full control over which members are injected. If you’d like to see an example of how to implement your own selection heuristics, take a glance at the code for the auto-wiring extension. (All the extension does is plug in its own selection heuristics when you load the AutoWiringModule.)

As always, if you have questions about any of this, feel free email me at nkohari at gmail dot com or find me on Twitter, and I’d be happy to help!

Cardboard Computers, or How I Started Programming

Mike Eaton recently started a new meme within my Twitter tribe: discussing how we found our way to the joy and light that is software development. :) My story might not be particularly interesting, but I figured I’d share it nonetheless.

Early On

I’ve been interested in science fiction as far back as I can remember, and so my fascination with computers developed at a very early age. Rather than play with my toys when I was young, I’d often take large pieces of cardboard cut from the sides of boxes and draw keyboards and screens on them with Sharpies. I’d sit in front of them for hours and pretend I was flying a space shuttle or doing whatever the hell else a young kid thinks computers can do.

When I was 6 years old, My grandpa bought me and my sister our first PC, a Tandy 1000 SX, with a CGA display, a roaring 7.16MHz 8088 processor and 384K of RAM. (And hard drive? We don’t need no stinking hard drive.) Rather than buy all sorts of games for the computer, my mom bought BASIC Computer Games, a book containing the BASIC source code to a bunch of different games. She would enter the source into GW-BASIC, and I would play the games. At first I just played the games, but eventually, I recognized that I could change the way the games worked by changing the way I entered the source code from the book. I started by making simple changes to the games (if I remember correctly I changed one so my name would be at the top of the high score list), and little by little the changes got more complex. Eventually I’d taught myself GW-BASIC.

When I was about 10, I wrote a half-assed word processor application. I learned the special command codes for bold, italic, and underline for dot-matrix printer, and made a cheap markup language — something like B(bold) would be printed as bold text. I was a strange kid. :) For some reason, I was amazed at how I could make the machine do what I wanted it to do. Once I was in middle school, I was introduced to the Apple IIc, and armed with my knowledge of GW-BASIC, I learned AppleBasic, and wrote some simple little games.

The Internet

Eventually, I graduated to a Packard Bell computer, which had a VGA output, a 386mHz processor, and a hard drive. This plunged me into the wonderful world of Windows 3.1. Around this time a phenomenon called “the Internet” was also starting to become popular, although the majority of the computing world was still oriented towards BBSes, and the Web was very much in its infancy. After trying and failing to convince my parents to sign up for CompuServe or AOL, I discovered the Akron Regional FreeNet (which is actually still around under the name ACORN), a dial-in BBS service through the local library. ARFNet also provided access to Gopher, and text-based access to the WWW via Lynx. It also had a service for IRC, which I used to meet other young geeks from the area with similar interests in programming. As it turned out, a couple of the people I met were volunteer administrators for ARFNet. They recommended me to the sysop, and I joined as an admin myself, which meant I could break out of the BBS system and get shell access to the two Solaris boxes that the system ran on. The other admins helped me learn UNIX and got me started learning C. I remember understanding C’s type system and functions, but never did anything very substantial with it because I couldn’t wrap my head around pointers and memory management. (That light bulb came on a few years later.)

Eventually, one of the other ARFNet admins set up a MUSH, which was basically Second Life before there was Second Life. :) It was a text-based virtual world that you could “walk” through and interact with objects in the environment. The objects were programmed in MUSHCode, which was kind of like LISP. I spent way too much time learning it in order to create a giant mansion and spaceships that could fly to different parts of the “world”. We ended up creating a virtual economy, along with shops and vending machines that you could use your “money” in.

In 1999, ARFNet introduced PPP, which meant that I had dial-in access to the Internet-at-large. Amazed at how much more advanced the Web was than any of the text-based stuff I’d seen before, I set out to teach myself HTML. I also got involved with IRC on a larger scale than just a few people, and I met some people who I’m still friends with even today.

College

Sometime around the turn of the millennium, I got my first job as a website developer at Signature Words & Pictures, one of the millions of design firms that decided to branch out from print design to interactivity during the first tech bubble. I was mostly a graphic artist there, but I also discovered PHP, which let me add some intelligence behind the layouts that I was creating. At work, I only had occasion to use PHP for little things like email response forms, but on my own time, I set out to learn everything I could about the language. I’ve always been interested in framework development, and I remember creating a templating system that let you embed tags in HTML, and when it was preprocessed, it would execute bits of PHP code — basically, a half-assed version of ColdFusion, although at the time I’d never heard of it.

At the same time, I started college at the University of Akron’s computer science program, where I was exposed more formally to concepts like combinatorics, data structures, computer architecture, assembly language, and later, object-oriented programming. My prior knowledge of most of the topics let me spend a lot of my time learning things outside the classroom, including C++, Perl, Java, and a little bit of C#. It wasn’t until probably my second year of college that I really understood what was going on in the computer.

The “Real World”

My first real programming job came in 2004, at the company that I’m still working at now. 2004 was not a good time for software developers, at least in the Northeast Ohio area — there were a lot of graduates, but not a lot of jobs available. I sent out about 100 copies of my resume to every company that I thought might be interested in having a software guy on staff, and got one response. As it turns out, one of my friends from college had recently been hired there, and he recommended me.

The company is traditionally a Linux development shop, and so I started out writing a lot of PHP and C++. A few months after I started, the company needed someone to learn C# to work on a new project, and I stepped up. I was immediately attracted to the simplicity of the language, and its familiar roots in C and Java. As I tend to do when exposed to a new technology, I devoured every scrap of information I could find on the .NET platform. A few years later, I’m hopelessly addicted.

Looking Back

The most fun I’ve had programming was seeing the original version of our RFID-tracking software in use at a live NASCAR event in 2005. At the time, I didn’t have a lot of experience watching users work with software I wrote, and I felt a tremendous amount of pride knowing that I’d been involved in creating something that was useful to others.

Knowing what I know now, I absolutely would still have become a software developer. It might sound odd, but I feel like I was born to do this stuff. It’s almost like my brain is hard-wired to understand computers. Neither of my parents are really that interested in technology, but somehow it got into my blood at an early age and it’s become a part of me. Sometimes are less fun than others, but this is definitely what I’m built to do.

To give advice to other would-be or novice programmers, I’ll steal a phrase often attributed to Confucius:

To know, is to know that you know nothing.

When I graduated from college, I was sure that I knew everything about how software was written. Every lesson I’ve learned since has taught me how little I (or anyone, for that matter) knows about what we do. Be confident in your abilities, but recognize that it is only through humility and great effort that you will find wisdom.

Cleveland Day of .NET Aftermath

Yesterday, I presented at the first annual Cleveland Day of .NET in Beachwood, and it was a fantastic experience. I was able to meet some brilliant people — although at times it was a little surreal, since I already “knew” them from Twitter and it was like I was meeting them all over again. The presentations that I attended were all excellent, and the conversations in the hallways and at lunch and dinner were even better.

Off the top of my head, it was great to meet: Dan Hounshell, Alan Stevens, Joe Fiorini, Mike Eaton, Leon Gersing, Sarah Dutkiewicz, John Stockton, Corey Haines, and Brian Prince. I know that I’ve forgotten some people from this list, and I’m sorry… the day was really a whirlwind, and my memory is horrible. If I’ve forgotten you, please post a comment or send me a tweet and I’ll make it right! Thanks very much to everyone involved in organizing, sponsoring, and attending the event.

For my first time presenting in front of a larger audience, I felt like it went pretty well. I was admittedly a little intimidated — although very excited — when it ended up being standing-room-only during my presentation. Thanks to everyone that came to watch me speak, and I hope you found it useful! Thanks also for the kind words and great feedback afterwards, and a special thanks to Alan Stevens for “refactoring” the projector when it decided to overheat halfway through. :D

Here are my slides, and you can also download them below:

As promised, a more complex code sample that illustrates some of the principles I discussed in the talk is available to download here. The code sample illustrates some of the more advanced uses of Ninject — stuff that I never could fit on a Keynote slide. I encourage you to tear it apart and get your hands dirty. The best way to learn the value of IoC is definitely to try it for yourself.

Slides (Keynote): designing-for-change.key.zip
Slides (PDF): designing-for-change.pdf.zip
Sample project: wargame.zip

Discord&Rhyme Joins The Lounge

Twitter is fantastic, because you can use it to meet some really interesting people. One such person I ran into in the Twitterverse is James Avery, who runs The Lounge, an internet ad network focused on technology. When he invited me to join the .NET Small Publishers Room, I was flattered, because I had already subscribed to several of the blogs that were featured there. It’s an honor to be featured alongside such auspicious company.

For those that read my blog from the site itself, you’ll notice a small ad in the top right corner. For those that read the RSS feed, you won’t notice any changes.