Prism,将Views和ViewModels与Unity连接,试图理解它

时间:2011-12-23 14:40:01

标签: c# wpf mvvm prism unity-container

  

使用Unity创建视图和视图模型

     

使用Unity作为依赖注入容器与使用类似   MEF,以及基于属性和基于构造函数的注入   支持的。主要区别在于类型通常是   在运行时没有隐含发现;相反,他们必须是   在容器中注册。

     

通常,您在视图模型上定义一个接口,以便视图   模型的特定具体类型可以与视图分离。对于   例如,视图可以通过a定义其对视图模型的依赖性   构造函数参数,如此处所示。 C#

public QuestionnaireView() 
{
    InitializeComponent(); 
}

public QuestionnaireView(QuestionnaireViewModel viewModel) : this() 
{
    this.DataContext = viewModel;
}
     

默认参数   构造函数是必要的,以允许视图在设计时工作   工具,例如Visual Studio和Expression Blend。

     

或者,您可以在上面定义只写视图模型属性   查看,如此处所示。 Unity将实例化所需的视图模型   在实例化视图后调用属性setter。 C#

public QuestionnaireView() 
{
    InitializeComponent(); 
}

[Dependency] 
public QuestionnaireViewModel ViewModel 
{
    set { this.DataContext = value; } 
}
     

视图模型类型已在Unity容器中注册,如图所示   这里。 C#

IUnityContainer container;
container.RegisterType<QuestionnaireViewModel>();
     

然后可以通过容器实例化视图,如图所示   这里。 C#

IUnityContainer container;
var view = container.Resolve<QuestionnaireView>();
  1. 如果我遗漏了有关注册ViewModel和实例化View的代码的最后一部分,并且只使用将ViewModel挂钩到View的两种方法中的任何一种(使用构造函数或使用属性)似乎ViewModel和View似乎一切正常。那么代码注册ViewModel并实例化View的需求是什么?

  2. 第一个例子,使用构造函数挂钩View和ViewModel,没有提到所有的Unity,所以Unity实际上是在这里使用吗?

  3. 使用基于属性的注射比使用基于construtor的注射有什么优势还是它们完全相同?

  4. 文本的第一部分说“*通常,您在视图模型上定义一个接口,以便视图模型的特定具体类型可以与视图分离”,然后给出一个示例。然而,这个例子根本没有提到接口。这里发生了什么,我错过了什么?

1 个答案:

答案 0 :(得分:13)

回答问题1&amp; 4

在您的示例中,viewmodel的类型为QuestionnaireViewModel,这是一个具体的类。由于它是一个具体的类,当您使用container.Resolve<QuestionnaireView>()解析视图时,unity将通过在幕后调用container.Resolve<QuestionnaireViewModel>()来为您实例化视图模型。

在这种情况下,注册viewmodel是多余的。但是,在使用依赖注入时,您通常希望使用接口而不是类,因此构造函数看起来像这样:

public QuestionnaireView(IQuestionnaireViewModel viewModel)
{
    this.DataContext = viewModel;
}

既然你的构造函数接收了一个接口而不是一个类作为参数,Unity就不知道你想要使用哪个接口实现。要告诉Unity,您需要将viewmodel注册到容器:

container.RegisterType<IQuestionnaireViewModel, QuestionnaireViewModel>();

所以现在当你解决你的观点时,Unity会查找它应该用作IQuestionnaireViewModel的实现的类,看看它是QuestionnaireViewModel并使用它。

回答问题2

正在使用Unity,因为为了使构造函数获取其参数,您需要使用容器来解析视图。如果您使用new QuestionnaireView()自己实例化视图,则不使用Unity,即不会发生构造函数或属性注入。

回答问题3

我认为这主要取决于什么更舒适以及需要使用注射成员的地方。很多时候,您只想在构造函数中设置局部变量,而不是仅为执行注入创建属性。

关于属性注入的一个好处是,您可以将container.BuildUp()方法用于使用new而不是container.Resolve<>()创建的实例。这样,即使在创建之后,您也可以将成员注入属性 - 这是构造函数注入无法做到的。