Вы не назначаете IDataService
для MainViewModel
здесь. Вы регистрируете сопоставление типов, поэтому ваш контейнер будет знать, что он должен возвращать DataService
всякий раз, когда требуется IDataService
.
Это связано с внедрением зависимости http://en.wikipedia.org/wiki/Dependency_injection
Контейнер DI auto-wire зависимости, поэтому, когда вам нужен определенный тип, вы можете позвонить
ServiceLocator.Current.GetInstance<IDataService>()
или
ServiceLocator.Current.GetInstance<MainViewModel>()
и т.д.. Если он может построить его (чтобы вы зарегистрировали свои типы), он разрешит для вас полный граф зависимостей.
Например, если ваш 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");
}
}
вывод:
Repository created
Service1 created
MainViewModel created
Service2 created
Поскольку вам нужен MainViewModel
(может быть, в SimpleIoC вам также необходимо зарегистрировать MainViewModel, в Unity он может разрешать конкретные классы без сопоставления), контейнер пытается его создать, но понимает, что MainViewModel
нуждается в IService
, и он находит значение по умолчанию из сопоставления, которое является Service1
, но он понимает, что Service1
требуется IRepository
, и он находит значение по умолчанию, поэтому он может передать Repository
в * Конструктор 1053 *, затем экземпляр Service1
для конструктора MainViewModel
. Все зависимости разрешены.
Вызов Foo
является примером того, как вы можете зарегистрировать более одного типа в одном интерфейсе. Внедрение зависимостей - гораздо более важная тема, но важна ее автоматическая разводка.