Entries
RSS 2.0

Comments
RSS 2.0

Conventions-Based Binding

In episode six of the ALT.NET podcast, Brad Wilson mentioned that we’ve only just touched the tip of the iceberg when it comes to dependency injection. He lamented that the existing frameworks have a configuration-based mindset, where you’re forced to wire your application’s components up in a very declarative fashion. He said he would prefer to see a DI framework that would allow you to favor convention over configuration.

This is a great idea, and it started the gears turning in my mind. Going with a more conventions-based mindset will let you wire your application up without the use of attributes, which helps to keep infrastructure concerns from cluttering your codebase. After an interesting question was posted to the Ninject user group, it occurred to me that Ninject supports a “conventions over configuration” mindset already.

For example, let’s say you have two sources for configuration in your application, a LocalConfigurationSource that loads configuration information from a local file, and a RemoteConfigurationSource that loads configuration from a remote database. Services that depend on configuration information will need one or the other of these services to set up configuration. Let’s say you have a consuming service that loads some of its configuration from the local source, and some from the remote source:


public class Service {
  public Service(IConfigurationSource remoteConfig, IConfigurationSource localSource) {
    //...
  }
}

In order to get Ninject to resolve these dependencies and call this constructor, you will need to declare bindings that differentiate between the two implementations of IConfigurationService. If you favor a declarative approach, you could create [Remote] and Local attributes, and use them to decorate the individual constructor arguments:


public class Service {
  public Service([Remote] IConfigurationSource remoteConfig, [Local] IConfigurationSource localSource) {
    //...
  }
}

Then your bindings would look like this:


Bind<IConfigurationSource>().To<RemoteConfigurationSource>()
  .WhereTargetHas<RemoteAttribute>();
Bind<IConfigurationSource>().To<LocalConfigurationSource>()
  .WhereTargetHas<LocalAttribute>();

However, if you’d rather not have to put the attributes in your constructor, you can rely on a conventions-based approach instead. For example, you can create a rule that says that if you want an instance of RemoteConfigurationSource, your argument has to begin with “remote”, and if you want an instance of LocalConfigurationSource, it has to begin with “local”. To do this, you would create bindings like this:


Bind<IConfigurationSource>().To<RemoteConfigurationSource>()
  .Only(When.Context.Target.Name.BeginsWith("remote"));
Bind<IConfigurationSource>().To<LocalConfigurationSource>()
  .Only(When.Context.Target.Name.BeginsWith("local"));

By using these bindings, your consuming service could have a constructor with no attributes, as shown in the first code example.

I’ve added an additional page to the Ninject dojo describing these ideas, and I’d like to hear some feedback. If you have ideas on how to improve upon this, I’d be very interested to hear them!

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.

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! :)

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!

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

Great IoC Presentation by Justin Etheredge

Justin Etheredge gave a great presentation on dependency injection and inversion of control last week at the Richmond Code Camp. It gives a very good introduction to DI, which is something that I’m going to try to tackle at the Cleveland Day of .NET in a few weeks. Plus, he uses Ninject in the examples and was kind enough to quote me in the presentation, so it’s got to be good, right? :)

Seriously, though, if you weren’t able to see the presentation, Justin’s posted the slides and related code samples on his blog. I highly recommend you check them out if you’re interested in learning more about dependency injection!

Come Hear Me Ramble

I will be speaking at the Cleveland Day of .NET on May 17th. If you’ve heard of this inversion of control and/or dependency injection stuff and would like to hear more, by all means come on up to sunny Cleveland! Here’s the abstract for my talk:

The old adage states that the only thing that remains constant is change, and nowhere is this more true than in software development. In this presentation, Nate Kohari describes how to apply the principles of inversion of control and dependency injection to create software that can adapt to changing requirements. Learn to break your monolithic app into loosely-coupled, highly-cohesive pieces… then glue them back together with an inversion of control container to create ultra-flexible code that you can bend to your will.

If you’ve never used dependency injection, this talk should prove to be a good introduction, and I’ll be happy to answer any and all questions. Or, if you’re already experienced with dependency injection, come see how Ninject can free you from the pain of XML!

Also, I’m still relatively new to public speaking, so there’s always the chance that I’ll completely choke and you can throw tomatoes. What’s more fun than that?

Announcing Ninject Contrib!

A few days ago, I accepted the first patch for Ninject, an NLog integration extension by Ivan Porto Carrero. Ivan subsequently created a couple other extensions for Ninject, and rather than put them directly into the main project, we decided to launch Ninject Contrib to collect contributions from the community.

If you’ve got any ideas for Ninject extensions, or if you come up with any examples that you’d like to share with the rest of Ninject users, feel free to post your idea in the Ninject developers group and I’ll set you up with commit access.

Major thanks to Ivan for his contributions, and his excellent ongoing series of Ninject-related articles!