Assuring that those IWantToRunAtStartup can actually run at startup

When building NServiceBus services based on the generic host, you may need to do some stuff whenever your service starts up and shuts down. The way to do that is to create classes that implement IWantToRunAtStartup, which will be picked up by the host and registered in the container as an implementation of that interface.

When the time comes to run whoever wants to run at startup, the host does a

to get all the relevant instances (or something similar if you aren’t using Windsor…).

If, however, one or more instances cannot be instantiated due to missing dependencies, you will get no kind of warning or error whatsoever! [1. At least this is the case when using Castle Windsor – I don’t know if this is also the behavior of other IoC containers… Maybe someone can clarify this…?] This means that the service will silently ignore the fact that one or more IWantToRunAtStartups could not be instantiated and run.

In order to avoid this error, I have written a test that looks somewhat like this:

I admit that the code is kind of clunky even though I distilled the interesting parts from some of the plumbing in our real test… moreover, our real test is iterating through all the possible configurations our container can have – one for each environment – so you can probably imagine that it’s not pretty 🙂

But who cares??? The test has proven almost infinitely useful already! Whenever something that wants to run at startup cannot run at startup, TeamCity gives us error messages like this:

5 thoughts on “Assuring that those IWantToRunAtStartup can actually run at startup

  1. I think Unity will fail with an exception, if you place unresolvable parameters in your constructor. I’m surprised that Windsor dont?

  2. Windsor does in fact throw (as it should) when you container.Resolve<ISomething>.

    But when you container.ResolveAll<ISomething>, it does not throw if one or more components registered as ISomething cannot be instantiated.

    Do you know how Unity behaves when doing a container.ResolveAll?

  3. @Krzysztof: Yes, you’re right – that would actually have worked, if it weren’t for the fact that the NServiceBus IBus that gets injected is not ready to send messages when it first gets registered in Windsor, causing our startables to be run with an uninitialized bus, which in turn means that no startables can send messages or manage subscriptions in their Start methods.

    Do you know if there’s a way around this?

    Obviously, if NServiceBus would just initialize itself before registering its instance in the container, we could have used startables instead of IWantToRunAtStartup.

  4. Thanks.. I spent all morning trying to figure out why one of my endpoints wouldn’t startup.. this was exactly it.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.