我正在使用适用于Windows 8的MVVM Light版本4;它包括SimpleIOC。在各种示例中,我有时会看到基于SimpleIoc请求对象的代码...有时它基于ServiceLocator ......
示例包括:
userToken = SimpleIoc.Default.GetInstance();
mainVM = ServiceLocator.Current.GetInstance();
使用SimpleIoc.Default.GetInstance和ServiceLocator.Current.GetInstance有什么区别?
如果没有区别,ServiceLocator是否让我可以选择改变我想要使用的IOC库的想法? ServiceLocator是否只提供了一个额外的抽象层,如果我对SimpleIoc感到满意,那么它是无关紧要的;或者,ServiceLocator是否会执行其他一些对IOC新手来说不明显的有用魔法?
感谢您的见解!
答案 0 :(得分:9)
在ViewModelLocator类中,您可能有以下代码行:
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc
实现IServiceLocator
接口,这意味着ServiceLocator
会在调用时将其用作DI源。
编辑:
好吧,人们想要“全脂而且不要吝啬奶油”的答案。我们走了! ServiceLocator
基本上是一个shell。服务定位器的代码是:
public static class ServiceLocator
{
private static ServiceLocatorProvider currentProvider;
public static IServiceLocator Current
{
get
{
return ServiceLocator.currentProvider();
}
}
public static void SetLocatorProvider(ServiceLocatorProvider newProvider)
{
ServiceLocator.currentProvider = newProvider;
}
}
是的,就是这样。
什么是ServiceLocatorProvider
?它是一个委托,它返回一个实现IServiceLocator
的对象。
SimpleIoc
实施IServiceLocator
。所以当我们这样做时:
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
我们将SimpleIoc
对象放入ServiceLocator
。您现在可以使用其中任何一个,因为无论是调用ServiceLocator.Current
还是SimpleIoc.Default
,您都会返回相同的对象实例。
那么,
之间有什么区别吗?userToken = SimpleIoc.Default.GetInstance();
mainVM = ServiceLocator.Current.GetInstance();
不。没有。两者都是暴露静态属性的单例,这是IServiceLocator
的实现。如上所述,无论您调用哪个对象,都会返回实现IServiceLocator
的对象实例。
为什么您可能希望用户的唯一原因ServiceLocator.Current.GetInstance()
,而不是SimpleIoc.Default.GetInstance()
是,在未来的某个时候,你可能会改变DI容器,如果你使用ServiceLocator
,你赢了不得不改变你的代码。
答案 1 :(得分:0)
基于Bugnion先生在MSDN上的article(在“注册类的各种方法”一节中),我假设IoC提供商的可互换性是使用ServiceLocator的唯一原因。
正如@FasterSolutions所述,SimpleIoc实现了IServiceLocator,因此我怀疑与你的关于抽象层的声明相反。我认为你应该使用ServiceLocator,但这没有经验证据;也许有人可以证明我错了(?)