棱镜,将视图和视图模型与Unity连接起来,试图理解它

本文关键字:视图 起来 Unity 模型 棱镜 连接 | 更新日期: 2023-09-27 18:18:37

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

使用

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

通常,您在视图模型上定义一个接口,以便视图 模型的特定具体类型可以与视图分离。为 例如,视图可以通过 构造函数参数,如下所示。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 和实例化视图的代码的最后一部分,而只是在此处使用将 ViewModel 挂接到视图的两种方法之一(使用构造函数或使用属性(,似乎 ViewModel 和视图似乎一切正常。那么,注册视图模型并实例化视图的代码需要什么呢?

  2. 第一个例子,使用构造函数挂接视图和视图模型,没有提到 Unity,那么这里真的使用 Unity 了吗?

  3. 与基于构造器的注入相比,使用基于属性的注入有什么优势,还是完全相同?

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

棱镜,将视图和视图模型与Unity连接起来,试图理解它

回答问题1和4

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

在这种情况下,注册视图模型是多余的。但是,在使用依赖注入时,您通常希望使用接口而不是类,因此构造函数如下所示:

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

现在,构造函数接收接口而不是类作为参数,Unity 不知道要使用接口的哪个实现。要告诉 Unity 这一点,您需要将视图模型注册到容器:

container.RegisterType<IQuestionnaireViewModel, QuestionnaireViewModel>();

所以现在当你解析你的视图时,Unity 会查找它应该使用哪个类作为IQuestionnaireViewModel的实现,看看它QuestionnaireViewModel并使用它。

回答问题2

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

回答问题3

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

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