Once upon a time, in the early days, the SimpleInjector.Extensions project contained a
“RegisterSingle(this Container, Type)” extension method, which allowed users to register a concrete type (by itself) as singleton. Users would write the following:
container.RegisterSingle(typeof(SomeType));
Which was expected to be the equivalent of:
container.RegisterSingle<SomeType>();
C# overload resolution however, always picks instance methods over extension methods (when one is applicable), and the C# compiler would turn this into:
container.RegisterSingle<Type>(typeof(SomeType));
Which means something completely different. The nasty thing however was, that IntelliSense in the IDE showed this method, which lead users to think that they could actually use this method, while a complete different registration was made. This extension methods was therefore removed from the extensions library.
Unfortunately there is currently no real good alternative for registering a single concrete type in a late bound fashion (using a Type).
There are basically three options:
- Add it again in the Extensions package, which is the most logical thing to do, since the this package contains all late bound stuff. This does mean however that a different name has to be chosen, to prevent the C# compiler from picking the wrong method. Something like 'RegisterSingleConcrete'. This however, is not intuitive, since all other methods are named RegisterSingle.
- Add it as instance method to the Container in the core library. This way we can keep the name 'RegisterSingle'. This does however 'pollute' the core API with a late bound registration method, which could also confuse starting developers.
- Abuse the current Container.RegisterSingle<TService>(TService) instance method to do a check if the given TService is of type Type, and call Container.RegisterSingle<TService>() under the covers. This seems like a clean solution, and when adding a ‘dummy’ RegisterSingle(Type) extension method in the extensions project, we could even have it pop-up during IntelliSense. But this is a bit of voodoo, and it will worry more advanced users that understand more about C# overload resolution (or when they do ‘goto definition’ on that method in the IDE.