Есть ли разница в намерениях сигнатур метода 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
, но я думаю, что это лучше оставить вопрос простым и сравнить только два метода одного и того же интерфейса для этого случая.)