LightInject
LightInject copied to clipboard
LightInject GetInstance generic extension forces using LightInject, name conflicts
Since a version 5.x LightInject started using an extension to handle generic GetInstance<TService> which seems like a step back from a IServiceFactory containing generic and non-generic method.
The reason for that is that outside of initialisation, IServiceFactory previously could be used without referencing LightInject in every file using generic GetInstance. Now reference is required and the LightInject namespace contains a lot of classes which can clash with project's namespaces i.e. LogLevel, LogEntry etc. which forces using aliases.
Instead of using extensions, can you switch back to generic methods on IServiceFactory or at least adding IGenericServiceFactory with only generic methods included.
Besides, adding logging to IoC container might be an overkill. Regardless of the issue, thanks for your great container.
Hi Michal and thanks for the kind words 👍
Since a version 5.x LightInject started using an extension to handle generic GetInstance which seems like a step back from a IServiceFactory containing generic and non-generic method.
The reason for having all the GetInstance methods as extension methods is that IServiceFactory is also implemented by the Scope class making it possible to resolve services directly from a scope.
IServiceFactory previously could be used without referencing LightInject in every file using generic GetInstance
I don't see how it ever could be possible to access the IServiceFactory interface without referencing the LightInject namespace. The reference to LightInject should only be needed in the composition root as long as you don't pass a reference to IServiceContainer around elsewhere in your application. Accessing the container outside the composition root or outside the near neighborhood of your application initialization code, should be avoided as that is recognized as the ServiceLocator pattern.
Instead of using extensions, can you switch back to generic methods on IServiceFactory or at least adding IGenericServiceFactory with only generic methods included.
That would be a breaking change and besides it would cause a lot of duplication/reimplementation of the GetInstance methods on the Scope class. 😃
I completely agree having a reference to LightInject is needed only in composition root yet IServiceFactory (or Scope) can be used by i.e. a lifetime service which can potentially have it exposed without the need to referencing LightInject in assemblies using the service, until you made the changes.
Hiding IoC implementation can be done by not exposing IServiceFactory explicitly and instead proxying it's methods by a custom interface but this adds unnecessary boilerplate for a simple use case of getting the instance dynamically when needed instead of injecting it in a constructor (performance/lazy initialization etc).
You can always keep using the extensions internally but at the same time implement missing methods on public interfaces or better yet add additional interfaces for generic methods and use the shared extensions implementation internally.
Another reason might be that extensions you are using for generic factory is just an implementation detail (I guess some casts witch checks). Some libraries like Protobuf have separate implementations of generic and non-generic serialization allowing separate optimization of both internally and not breaking the usage for users. Separate generic and non-generic factory interfaces (with a shared interface containing both) would solve this problem without breaking compatibility.
Hope my point of view is not too convoluted ;)