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
你没有IDataService在MainViewModel这里分配任何东西.您正在注册类型映射,因此您的容器将意识到它应该DataService在IDataService需要时返回.
这与依赖注入 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,它找到默认的,所以它可以传递Repository给Service1构造函数,然后Service1实例传递给MainViewModel构造函数.所有依赖项都已解决.
该Foo调用是一个示例,说明如何将多个类型注册到同一个接口.依赖注入是一个更大的主题,但自动布线是其中的一个重要部分.