我的解决方案中有两个项目, MyApp.Shell 和 MyApp.ModuleFoo
MyApp.Shell的Unity Bootstrapper
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!”。
感谢您的帮助。
添加了MyApp.FooModule的初始化代码
事实证明RegisterViewWithRegion有两个重载。从Prism的文档中,当使用我正在使用的重载时,会创建一个新的视图实例。我假设这也创建了一个新的FooViewModel实例。
另一个重载使用委托来解析FooView。文档说明这种重载在“ViewModel-first”方法中使用。我要回答这个问题,但如果有人有任何额外的见解,我很乐意听到。
答案 0 :(得分:4)
// Somehow, Unity sees this class and registers the type. public class FooViewModel : ViewModelBaseClass
...
我很惊讶您说这是因为Unity默认情况下不在容器内注册类型。您必须以编程方式或在配置文件中告诉它这样做。
当你拥有具体的类(不是接口)时,它们将自动由Unity创建,无论它们是否已注册。如果不是,则默认行为是每次都创建一个新实例。也没有适用终身管理。
至于你的问题:
只需在模块初始化中注册一种类型。
Container.RegisterType<FooViewModel>(new ContainerControlledLifetimeManager());
生命周期管理器将指示unity只创建一个视图模型的实例。