SimpleIoc.Default.GetInstance和ServiceLocator.Current.GetInstance之间有区别吗

use*_*314 9 inversion-of-control mvvm-light

我正在使用适用于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新手来说并不明显?

感谢您的见解!

Fas*_*ons 9

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

public ViewModelLocator()
{
  ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
Run Code Online (Sandbox Code Playgroud)

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

是的,就是这样.

什么ServiceLocatorProvider?它是一个委托,它返回一个实现的对象IServiceLocator.

SimpleIoc实施IServiceLocator.所以当我们这样做时:

ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
Run Code Online (Sandbox Code Playgroud)

我们把我们的SimpleIoc对象放入了ServiceLocator.您现在可以使用其中任何一个,因为无论是调用ServiceLocator.Current还是SimpleIoc.Default返回相同的对象实例.

那么,两者之间有什么区别吗?

userToken = SimpleIoc.Default.GetInstance();

mainVM = ServiceLocator.Current.GetInstance();
Run Code Online (Sandbox Code Playgroud)

不.没有.两者都是暴露静态属性的单例,这是一个实现IServiceLocator.如上所述,IServiceLocator无论您调用哪个对象,都将返回相同的对象实例.

您可能想要使用的唯一原因ServiceLocator.Current.GetInstance()而不是SimpleIoc.Default.GetInstance()在将来某个时候您可以更改DI容器,如果您使用ServiceLocator,则不必更改代码.