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.
Grazie, molto utile :) – Qirat
@Qirat benvenuto :) –