9

我正在使用适用于 Windows 8 的 MVVM Light 第 4 版;它包括 SimpleIOC。在各种示例中,我有时会看到基于 SimpleIoc 请求对象的代码......有时它基于 ServiceLocator......

示例包括:

userToken = SimpleIoc.Default.GetInstance();

mainVM = ServiceLocator.Current.GetInstance();

使用 SimpleIoc.Default.GetInstance 和 ServiceLocator.Current.GetInstance 有什么区别?

如果没有区别,ServiceLocator 是否只是让我可以选择改变我对要使用的 IOC 库的想法?如果我对 SimpleIoc 感到满意,ServiceLocator 是否只是提供了一个无关紧要的附加抽象层?或者,ServiceLocator 是否执行了其他一些对我们 IOC 新手来说并不明显的有用魔法?

感谢您的洞察力!

4

2 回答 2

9

在您的 ViewModelLocator 类中,您可能有以下代码行:

public ViewModelLocator()
{
  ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

SimpleIoc实现IServiceLocator接口,这意味着ServiceLocator调用时将使用它作为 DI 源。

编辑:

好的,人们想要“全脂且不放过奶油”的答案。开始了!

ServiceLocator基本上是一个外壳。服务定位器的代码是:

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,则不必更改代码。

于 2013-01-02T14:41:22.647 回答
0

根据 Bugnion 先生在 MSDN 上的文章(在“注册类的各种方法”一节中),我假设 IoC 提供程序的可互换性是使用 ServiceLocator 的唯一原因。

正如@FasterSolutions 所说,SimpleIoc 实现了 IServiceLocator,所以我怀疑与您关于抽象层的说法相反的是正确的。我认为您应该使用 ServiceLocator,但这没有经验证据;也许有人可以证明我错了(?)

于 2014-02-28T08:58:00.417 回答