2012-01-29 64 views
7

这个问题看起来幼稚,但是我不明白这个代码在ViewModelLocator.cs文件:我们使用的DataService摆脱WCF服务的数据(MVVMLight ViewModelLocator注册的DataService

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

    if (ViewModelBase.IsInDesignModeStatic) 
    { 
     SimpleIoc.Default.Register<IDataService, Design.DesignDataService>(); 
    } 
    else 
    { 
     SimpleIoc.Default.Register<IDataService, DataService>();   
    } 

    SimpleIoc.Default.Register<MainViewModel>(); 
} 

我见例如)并将其分配给MainViewModel。但是如果我注册了多个ViewModel呢?像这样:

static ViewModelLocator() 
{ 
    .... 
    SimpleIoc.Default.Register<MainViewModel>(); 
    SimpleIoc.Default.Register<Page2ViewModel>(); 
} 

,让我们说我有另一种的DataService(DataService2为例),但是这一次,我会与Page2ViewModel使用。我怎样才能做到这一点?

此外,如果有人可以帮助我(甚至给我一个链接阅读)关于上述代码。我不知道它的意思。

回答

21

您在这里没有为MainViewModel分配任何IDataService。您正在注册一个类型映射,因此只要需要IDataService,您的容器就会知道它应该返回DataService

这与依赖注入http://en.wikipedia.org/wiki/Dependency_injection

的DI容器自动线的依赖关系,因此,当你需要一个特定的类型,你可以调用

ServiceLocator.Current.GetInstance<IDataService>()

ServiceLocator.Current.GetInstance<MainViewModel>() 

如果它可以构建它(所以你注册你的类型),它会为你解决完整的依赖关系图。

例如,如果您MainViewModelIDataService一个构造函数依赖,你是不是在设计模式,一个DataService将被注入到MainViewModel构造。不要害怕从流行词注入,它只是一个调用具有适当参数的MainViewModel构造函数:)。因此,MainViewModel这里不会干涉Page2ViewModel

我做了一个简单的示例,为您展示发生了什么(我用的团结,http://unity.codeplex.com/,但语法几乎是相同的):

class Program 
{ 
    static void Main(string[] args) 
    { 
     var container = new UnityContainer(); 
     container.RegisterType<IService, Service1>(); 
     container.RegisterType<IService, Service2>("MySpecificService"); 
     container.RegisterType<IRepository, Repository>(); 
     ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(container)); 

     var viewModel = ServiceLocator.Current.GetInstance<MainViewModel>(); 
     viewModel.Foo(); 
    } 
} 

interface IService 
{ 
} 

interface IRepository 
{ 
} 

class Service1 : IService 
{ 
    public Service1(IRepository repository) 
    { 
     Console.WriteLine("Service1 created"); 
    } 
} 

class Service2 : IService 
{ 
    public Service2() 
    { 
     Console.WriteLine("Service2 created"); 
    } 
} 

class Repository : IRepository 
{ 
    public Repository() 
    { 
     Console.WriteLine("Repository created"); 
    } 
} 

class MainViewModel 
{ 
    public MainViewModel(IService service) 
    { 
     Console.WriteLine("MainViewModel created"); 
    } 

    public void Foo() 
    { 
     var specificService = ServiceLocator.Current.GetInstance<IService>("MySpecificService"); 
    } 
} 

输出为:

Repository created 
Service1 created 
MainViewModel created 
Service2 created 

因为你需要一个MainViewModel(也许在SimpleIoC中,你也需要注册MainViewModel,在Unity中,它可以解析具体类而不映射),容器试图创建一个,但它意识到MainViewModel需要一个IService,并发现从映射,这是Service1默认之一,但它意识到Service1需要一个IRepository,并且它找到的默认的,因此它可以通过一个RepositoryService1构造函数,则Service1实例到MainViewModel构造函数。所有的依赖关系解决。

Foo调用是一个示例,您可以向同一接口注册多个类型。依赖注入是一个更大的话题,但自动布线是它的重要组成部分。

+0

谢谢,非常有帮助:) – Qirat 2012-01-30 11:49:29

+0

@Qirat欢迎:) – 2012-01-30 11:53:25