vendredi 15 décembre 2017

Safely making wide-reaching change to IoC/DI config

I've been contributting to a small-ish codebase (maybe ~10 pages? and 20-30 services/controllers) which uses Ninject for Ioc/DI.

I've discovered that in the Ninject Kernel it is configured to BindDefaultInterface. That means that if you ask it for an IFoo, it will go looking for a Foo class.

But it does that based on the string pattern, not the C# inheritance. That means that MyFoo : IFoo won't bind, and you could also get other weird "coincidental" bindings, maybe?

It all works so far, because everyone happens to have called their WhateverService interface IWhateverService.

But this seems enormously brittle and unintuitive to me. And it specifically broke when I wanted to rename my live FilePathProvider : IFilePathProvider to be AppSettingsBasedFilePathProvider (as opposed to the RootFolderFilePathProvider, or the NCrunchFilePathProvider which get used in Test) on the basis of that telling you what it did :)

There are a couple of alternative configurations:

  • BindToDefaultInterfaces (note plural) which will bind MyOtherBar to IMyOtherBar, IOtherBar & IBar (I think)
  • BindToSingleInterface works if every class implements exactly 1 interface.
  • BindToAllInterfaces does exactly what it sounds like.

I'd like to change to those, but I'm concerned about introducing obscure bugs whereby some class somewhere stops binding in the way that it should, but I don't notice.

Is there any advice for how to test this / make this change with a reasonable amount of safety (i.e. more than "do it and hope", anyway!) without just trying to work out how to excercise EVERY possible component.

Aucun commentaire:

Enregistrer un commentaire