Is there a difference in intentions of the method signatures IServiceProvider.GetService(Type serviceType)
and IServiceLocator.GetInstance(Type serviceType)
? If so, what is the distinction?
I've always treated them as equivalent but made a choice to use a single method for consistency. This seems like a good enough solution to dealing with the two interfaces, but I'd really like to know how their usages were actually intended so that I can be sure I am using the right one in the right place. If their intention is in fact the same, then is there any reason for having multiple sets of semantics for the same purpose? (I understand that the GetInstance
signature was recommended during the inception of Microsoft.Practices.ServiceLocation
, but this doesn't really seem like a sound reason to introduce the duplication).
Why I'm confused
Below is a list of sometimes contradictory facts I have found in trying to find the answer to this question, as well as my interpretation thereof. I am including these so that my question can be addressed in context of all the information that is already known about this topic.
The MSDN documentation for
IServiceProvider
says that theGetService(Type serviceType)
method should returnA service object of type serviceType.
-or-
null if there is no service object of type serviceType.The MSDN documentation for
IServiceLocator
lacks method documentation but the summary in the VS Object Browser ofGetInstance(Type serviceType)
says that the method returns "the requested service instance". However, there is also an exception entry in the documentationIServiceLocator
that says that anActivationException
should be thrown if there is an error resolving the service instance.ActivationException
is located in theMicrosoft.Practices.ServiceLocation
namespace which was introduced years afterIServiceProvider
was introduced. So, it is understandable that theIServiceProvider
does not refer to the exception. That being said, theIServiceLocator
interface's documentation says nothing about returningnull
if no result is found. It also isn't clear whether or not the absence of an implementation of the requested service type should constitute an exception.Should the absence of an implementation for a service type cause an
ActivationException
inIServiceLocator
implementations? It doesn't look like it. The implementation template forIServiceLocator
ignores any concept of a non-null post-condition.The implementation template for
IServiceLocator
also treatsIServiceProvider.GetService(Type)
as alternative syntax forIServiceLocator.GetInstance()
. Does this count as a violation of Liskov (due to throwing an exception in subtype that is not declared on the base type), or, would that actually require a difference in the implementation rather than the exceptions declared on the interface's method signatures? What I'm getting at is: Are we sure that theServiceLocatorImplBase
implementation template forIServiceLocator
implements both interfaces correctly? Would it be a better representation of the interfaces' intentions for theIServiceProvider
to wrap theGetInstance
call in a try block, and returnnull
when an exception is caught?Addendum: One other issue related to this is the correspondence of
IServiceLocator.GetAllInstances(Type)
toIServiceLocator.GetInstance(Type)
. Specifically, For any type, T, should an implementation ofIServiceLocator.GetAllInstances(typeof(T))
return the same result asIServiceLocator.GetInstance(typeof(IEnumerable<>).MakeGenericType(typeof(T))
? (It's easy to see how this relates to theIServiceProvider
correspondence, but I think it's better to keep the question simple and only compare the two methods of the same interface for this case.)