IServiceProvider.GetService(Type serviceType)
方法签名和的意图有区别IServiceLocator.GetInstance(Type serviceType)
吗?如果有,有什么区别?
我一直将它们视为等效的,但为了保持一致性,我选择使用单一方法。这似乎是处理这两个接口的一个足够好的解决方案,但我真的很想知道它们的实际用途是什么,以便我可以确定我在正确的地方使用了正确的接口。 如果他们的意图实际上是相同的,那么有任何理由为同一目的使用多组语义吗?(我知道签名是在 开始时推荐的,GetInstance
Microsoft.Practices.ServiceLocation
但这似乎并不是引入重复的合理理由)。
为什么我很困惑
下面列出了我在试图找到这个问题的答案时发现的有时相互矛盾的事实,以及我对它的解释。我将这些包括在内,以便可以在有关该主题的所有已知信息的背景下解决我的问题。
MSDN 文档
IServiceProvider
说该方法GetService(Type serviceType)
应该返回serviceType 类型的服务对象。
-或 -如果没有serviceType类型的服务对象,则为
null。MSDN 文档
IServiceLocator
缺少方法文档,但 VS 对象浏览器中的摘要说GetInstance(Type serviceType)
该方法返回“请求的服务实例”。但是,文档中还有一个异常条目IServiceLocator
,指出ActivationException
如果解析服务实例时出现错误,则应抛出一个异常条目。ActivationException
位于Microsoft.Practices.ServiceLocation
引入多年后IServiceProvider
引入的命名空间中。因此,可以理解的IServiceProvider
是 不指异常。话虽如此,IServiceLocator
接口的文档没有说明null
如果没有找到结果就返回。也不清楚是否缺少所请求的服务类型的实现应构成例外。缺少服务类型的实现是否会导致
ActivationException
inIServiceLocator
实现? 看起来不像。的实现模板IServiceLocator
忽略任何非空后置条件的概念。的实现模板
IServiceLocator
也被IServiceProvider.GetService(Type)
视为IServiceLocator.GetInstance()
. 这是否算作违反 Liskov(由于在未在基类型上声明的子类型中抛出异常),或者,这实际上需要实现差异而不是接口方法签名上声明的异常?我的意思是:我们确定ServiceLocatorImplBase
实现模板IServiceLocator
正确实现了这两个接口吗?IServiceProvider
将调用包装GetInstance
在 try 块中并null
在捕获到异常时返回 是否会更好地表示接口的意图?附录:与此相关的另一个问题是 to 的对应
IServiceLocator.GetAllInstances(Type)
关系IServiceLocator.GetInstance(Type)
。具体来说,对于任何类型 T,其实现是否应该IServiceLocator.GetAllInstances(typeof(T))
返回与 ? 相同的结果IServiceLocator.GetInstance(typeof(IEnumerable<>).MakeGenericType(typeof(T))
? (很容易看出这与IServiceProvider
对应关系有什么关系,但我认为最好保持问题简单,只比较这种情况下同一接口的两种方法。)