Есть ли разница в намерениях сигнатур метода IServiceProvider.GetService(Type serviceType) и IServiceLocator.GetInstance(Type serviceType)? Если да, то какое это различие?
Я всегда рассматривал их как эквивалентные, но сделал выбор, чтобы использовать один метод для согласованности. Это похоже на достаточно хорошее решение для работы с двумя интерфейсами, но я действительно хотел бы знать, как их использование было на самом деле предназначено, чтобы я мог быть уверен, что использую правильный вариант в нужном месте. Если их намерение на самом деле то же самое, то есть ли какая-либо причина наличия нескольких наборов семантики с той же целью? (я понимаю, что подпись GetInstance была рекомендована в начале Microsoft.Practices.ServiceLocation, но на самом деле это не кажется разумной причиной для введения дублирования).
Почему я запутался
Ниже приведен список иногда противоречивых фактов, которые я нашел, пытаясь найти ответ на этот вопрос, а также мою интерпретацию. Я включаю их, чтобы мой вопрос мог быть рассмотрен в контексте всей информации, которая уже известна об этой теме.
-
документация MSDN для
IServiceProviderговорит, что методGetService(Type serviceType)должен возвращатьОбъект службы типа serviceType.
-или-
null, если нет объекта службы типа serviceType. -
документация MSDN для
IServiceLocatorотсутствует документация по методу, но резюме в обозревателе объектов VSGetInstance(Type serviceType)говорит, что метод возвращает "запрошенный экземпляр службы". Однако в документацииIServiceLocatorимеется также запись об исключении, в которой говорится, что при возникновении ошибки в экземпляре службы должен быть выброшенActivationException. -
ActivationExceptionнаходится в пространстве именMicrosoft.Practices.ServiceLocation, который был введен через несколько лет после введенияIServiceProvider. Таким образом, понятно, чтоIServiceProviderне относится к исключению. При этом в документации по интерфейсуIServiceLocatorничего не говорится о возвратеnull, если результат не найден. Также неясно, является ли исключение внедрением запрашиваемого типа услуги. -
Если отсутствие реализации для типа службы вызывает реализацию
ActivationExceptionвIServiceLocator? Это не похоже на это. Шаблон дляIServiceLocatorигнорирует любую концепцию непустого пост-состояния. -
шаблон реализации для
IServiceLocatorтакже рассматриваетIServiceProvider.GetService(Type)как альтернативный синтаксис дляIServiceLocator.GetInstance(). Означает ли это как нарушение Лискова (из-за исключения исключения в подтипе, который не объявлен в базовом типе), или, действительно ли это потребует разницы в реализации, а не в исключениях, объявленных в сигнатурах метода интерфейса? Я уверен, что шаблон реализацииServiceLocatorImplBaseдляIServiceLocatorправильно реализует оба интерфейса? Было бы лучше отображать намерения интерфейсов дляIServiceProviderдля обертывания вызоваGetInstanceв блоке try и возвратаnullпри обнаружении исключения? -
Добавление: Еще одна проблема, связанная с этим, - это соответствие
IServiceLocator.GetAllInstances(Type)-IServiceLocator.GetInstance(Type). В частности, Для любого типа T, если реализацияIServiceLocator.GetAllInstances(typeof(T))возвращает тот же результат, что иIServiceLocator.GetInstance(typeof(IEnumerable<>).MakeGenericType(typeof(T))? (легко видеть, как это относится к корреспонденцииIServiceProvider, но я думаю, что это лучше оставить вопрос простым и сравнить только два метода одного и того же интерфейса для этого случая.)