2012-01-29 12 views
7

Questa domanda potrebbe sembrare ingenua, ma non ho potuto capire questo codice nel file ViewModelLocator.cs:MVVMLight ViewModelLocator registrazione 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>(); 
} 

vedo che usiamo un DataService per ottenere i dati (da servizio WCF per esempio) e assegnandolo a MainViewModel. Ma cosa succede se sto registrando più di un ViewModel? in questo modo:

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

e diciamo che ho un altro DataService (DataService2 per esempio), ma questo userò con il Page2ViewModel. Come lo posso fare?

Inoltre, se qualcuno può aiutarmi (o anche darmi un collegamento per leggere) sul codice di cui sopra. Non ho idea di cosa significhi.

risposta

21

Non si sta assegnando alcun IDataService allo MainViewModel qui. Si sta registrando una mappatura del tipo, quindi il contenitore sarà consapevole del fatto che deve restituire un valore DataService ogni volta che è richiesto un numero IDataService.

questo è legato all'iniezione dipendenzahttp://en.wikipedia.org/wiki/Dependency_injection

Il contenitore DI auto-fili le dipendenze, in modo che quando hai bisogno di un tipo specifico, è possibile chiamare

ServiceLocator.Current.GetInstance<IDataService>()

o

ServiceLocator.Current.GetInstance<MainViewModel>() 

ecc. Se è in grado di costruirlo (così registrato i tipi), risolverà il grafico completo delle dipendenze.

Ad esempio, se il MainViewModel ha una dipendenza costruttore su IDataService, e non si è in modalità di progettazione, un DataService sarà iniettato al costruttore MainViewModel. Non aver paura della parola d'ordine iniettata, è solo una chiamata al costruttore MainViewModel con i parametri appropriati :).

Quindi, MainViewModel non interferirà con Page2ViewModel qui.

Ho fatto un semplice esempio per di dimostrare ciò che accade (io ho usato Unità, http://unity.codeplex.com/, ma la sintassi è quasi lo stesso):

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"); 
    } 
} 

l'output è:

Repository created 
Service1 created 
MainViewModel created 
Service2 created 

Perché hai bisogno di un MainViewModel (forse in SimpleIoC devi registrare anche MainViewModel, in Unity, può risolvere le classi concrete senza mappatura), il contenitore cerca di crearne uno, ma si rende conto che.210 ha bisogno di un IService, e trova quella predefinita dalla mappatura, che è Service1, ma rende conto che Service1 necessita di un IRepository, e trova quella di default, in modo che possa passare un Repository al costruttore Service1, l'istanza Service1 al costruttore MainViewModel. Tutte le dipendenze risolte.

La chiamata Foo è un esempio di come è possibile registrare più di un tipo sulla stessa interfaccia. L'iniezione di dipendenza è un argomento molto più grande, ma l'auto-cablaggio è una parte importante di esso.

+0

Grazie, molto utile :) – Qirat

+0

@Qirat benvenuto :) –

Problemi correlati