2012-01-29 68 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