这个问题可能看起来很幼稚,但我无法理解 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>();
}
我看到我们使用 DataService 来获取数据(例如从 WCF 服务)并将其分配给 MainViewModel。但是如果我注册了多个 ViewModel 怎么办?像这样:
static ViewModelLocator()
{
....
SimpleIoc.Default.Register<MainViewModel>();
SimpleIoc.Default.Register<Page2ViewModel>();
}
假设我有另一个 DataService(例如 DataService2),但这个我将与 Page2ViewModel 一起使用。我怎样才能做到这一点?
另外,如果有人可以帮助我(甚至给我一个阅读链接)上面的代码。我不知道这意味着什么。
最佳答案
您没有分配任何 IDataService
到MainViewModel
这里。你正在注册一个类型映射,所以你的容器会知道它应该返回一个 DataService
每当 IDataService
必需的。
这与 有关依赖注入(inject) http://en.wikipedia.org/wiki/Dependency_injection
DI 容器 汽车线依赖项,因此当您需要特定类型时,您可以调用ServiceLocator.Current.GetInstance<IDataService>()
或者
ServiceLocator.Current.GetInstance<MainViewModel>()
等等。如果它可以构建它(所以你注册了你的类型),它将为你解析完整的依赖图。
例如,如果您的
MainViewModel
构造函数依赖于 IDataService
,并且您不在设计模式下,DataService
将注入(inject) MainViewModel
构造函数。不要害怕注入(inject)的流行语,它只是使用适当的参数调用 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
到Service1
构造函数,然后是 Service1
MainViewModel
的实例构造函数。所有的依赖关系都解决了。Foo
call 是一个示例,您可以如何将多个类型注册到同一接口(interface)。依赖注入(inject)是一个更大的话题,但 Autowiring 是其中的重要组成部分。
关于wpf - MVVMLight ViewModelLocator 注册数据服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9052180/