MVVMLight ViewModelLocator注册dataservice

Qir*_*rat 7 silverlight wpf mvvm mvvm-light viewmodellocator

这个问题可能看起来很幼稚,但我无法理解ViewModelLocator.cs文件中的这段代码:

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

我看到我们使用DataService来获取数据(例如来自WCF服务)并将其分配给MainViewModel.但是,如果我注册了多个ViewModel怎么办?像这样:

static ViewModelLocator()
{
    ....
    SimpleIoc.Default.Register<MainViewModel>();
    SimpleIoc.Default.Register<Page2ViewModel>();
}
Run Code Online (Sandbox Code Playgroud)

并且假设我有另一个DataService(例如DataService2),但是这个我将与Page2ViewModel一起使用.我怎样才能做到这一点?

此外,如果有人可以帮助我(或甚至给我一个阅读链接)关于上述代码.我不知道这意味着什么.

Pet*_*rfy 21

你没有IDataServiceMainViewModel这里分配任何东西.您正在注册类型映射,因此您的容器将意识到它应该DataServiceIDataService需要时返回.

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

DI容器自动连接依赖项,因此当您需要特定类型时,可以调用

ServiceLocator.Current.GetInstance<IDataService>()

要么

ServiceLocator.Current.GetInstance<MainViewModel>()
Run Code Online (Sandbox Code Playgroud)

等等.如果能建立它(所以您注册的类型),将解决你的全部依赖关系图.

例如,如果您MainViewModel具有构造函数依赖项IDataService,并且您未处于设计模式,DataService则会将一个注入到MainViewModel构造函数中.不要害怕注入的流行语,它只是用适当的参数调用MainViewModel构造函数:).

所以,MainViewModel不会干涉Page2ViewModel这里.

我为你做了一个简单的示例来演示会发生什么(我使用Unity,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");
    }
}
Run Code Online (Sandbox Code Playgroud)

输出是:

Repository created
Service1 created
MainViewModel created
Service2 created
Run Code Online (Sandbox Code Playgroud)

因为你需要一个MainViewModel(也许在SimpleIoC中你需要注册MainViewModel,在Unity中,它可以解析具体类而不需要映射),容器试图创建一个,但它意识到MainViewModel需要一个IService,它从映射中找到默认的一个,它Service1,但它意识到Service1需要一个IRepository,它找到默认的,所以它可以传递RepositoryService1构造函数,然后Service1实例传递给MainViewModel构造函数.所有依赖项都已解决.

Foo调用是一个示例,说明如何将多个类型注册到同一个接口.依赖注入是一个更大的主题,但自动布线是其中的一个重要部分.