c#-模块中的棱镜,Unity和默认类型注册

技术领域

> 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仅创建视图模型的一个实例.

上一篇:c# – Prism NavigationService获取以前的视图名称


下一篇:[转]Blue Prism Interview Questions and Answers