技术领域
> C#4.0
> Prism 4与Unity for DI
> WPF
> MVVM
前言
我的解决方案中有两个项目,MyApp.Shell和MyApp.ModuleFoo
MyApp.Shell的Unity引导程序
protected override IModuleCatalog CreateModuleCatalog()
{
// Module assemblies are read from a directory.
DirectoryModuleCatalog moduleCatalog = new DirectoryModuleCatalog();
moduleCatalog.ModulePath = @".\Modules";
return moduleCatalog;
}
项目MyApp.ModuleFoo包含一个视图和一个视图模型.
ViewModel
// Somehow, Unity sees this class and registers the type.
public class FooViewModel : ViewModelBaseClass
{
public string FooText
{
get { return "Foo!"; }
}
}
风景
<Label Content={Binding FooText} />
视图的代码背后
// Unity automatically sees this as Constructor Injection,
// which is exactly what I desire.
public FooView(FooViewModel viewModel)
{
DataContext = viewModel;
...
}
MyApp.FooModule的初始化
也许在区域管理器中注册FooView是在无意中向Unity注册FooViewModel?
public void Initialize()
{
var regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
regionManager.RegisterViewWithRegion("FooRegion", typeof(FooView));
}
该视图正确显示“ Foo!”.
问题
>如何告诉Unity仅注册FooViewModel的单个实例?
>另外,(并且我在这里在想),我如何告诉统一不要注册FooViewModel?
谢谢您的帮助.
编辑:
添加了MyApp.FooModule的初始化代码
编辑(解决方案):
事实证明RegisterViewWithRegion有两个重载.根据Prism的文档,当使用我正在使用的重载时,将创建该视图的新实例.我假设这还会创建FooViewModel的新实例.
另一个重载使用委托来解析FooView.该文档说,此重载在“ ViewModel-first”方法中使用.我将回答这个问题,但是如果有人有其他见解,我很想听听.
解决方法:
// Somehow, Unity sees this class and registers the type.
public class FooViewModel : ViewModelBaseClass
…
我很惊讶您这么说,因为默认情况下Unity不会在容器内注册类型.您必须告诉它以编程方式或在配置文件中执行此操作.
当您拥有具体的类(而不是接口)时,无论是否注册,它们都会由Unity自动创建.如果不是,默认行为是每次创建一个新实例.也没有应用生命周期管理.
关于您的问题:
仅在模块初始化内注册一种类型.
Container.RegisterType<FooViewModel>(new ContainerControlledLifetimeManager());
生命周期管理器将指示unity仅创建视图模型的一个实例.