An application can pass every test, run flawlessly in development and crash on its first call in Production because a service it needs is null. No compiler and no unit test sees that, because the error isn’t in a method but in the wiring, and in development the wiring is different from Production. In this lesson you reproduce the error in a small practice application, write the test that finds it, and give the Kladde a startup test that will report something like this in the pull request from now on.

Field report: a registration quietly returns null

In one project a library was updated. It registered a type anew with a key and, without the documentation making a point of it, the same type additionally without a key, with a factory that returned null. The application asked for the type without a key. The container said nothing, because from its point of view a factory may return whatever it likes. The tests ran in development, with a different configuration, and were green. In Production a service received null in its constructor, and for a week every request failed at a place where nobody had expected null.

The cause was a library, but you can easily make the same kind of mistake yourself. Three typical forms:

  • A factory returns null. AddSingleton(sp => …Get<T>()!): Get<T>() returns null when the section is missing from the configuration, and the ! silences the compiler.
  • A service isn’t registered at all. It appears only in a branch if (builder.Environment.IsDevelopment()) or was forgotten during a refactoring.
  • A singleton holds on to a scoped service (lesson 2.3.3). The service is created once and tied to the first DbContext forever.