【问题标题】:Prism, connecting Views and ViewModels with Unity, trying to understand itPrism,用 Unity 连接 Views 和 ViewModels,试图理解它
【发布时间】:2012-01-26 21:15:21
【问题描述】:

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

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

通常,您在视图模型上定义一个接口,以便视图 模型的具体具体类型可以从视图中解耦。为了 例如,视图可以通过 构造函数参数,如此处所示。 C#

public QuestionnaireView() 
{
    InitializeComponent(); 
}

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

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

或者,您可以在 视图,如图所示。 Unity 将实例化所需的视图模型 并在实例化视图后调用属性设置器。 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>();
    1234563看来 ViewModel 和 View 似乎一切正常。那么注册ViewModel和实例化View的代码需要什么?
  1. 第一个示例,使用构造函数挂钩 View 和 ViewModel,完全没有提到 Unity,那么这里真的使用 Unity 吗?

  2. 与基于构造函数的注入相比,使用基于属性的注入是否有任何优势,或者它们是否完全相同?

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

【问题讨论】:

  • 我喜欢使用微软的 Prism 库,但是我觉得他们使用 Views 进行导航的例子是个坏主意,因为我认为 ViewModels 应该在使用 MVVM 设计模式时控制应用程序流,而不是 Views .如果您尝试在应用程序中使用 MVVM,我建议您使用 ApplicationViewModel 来处理窗口管理,并让 WPF 通过 DataTemplates 解析要使用的视图。

标签: c# wpf mvvm prism unity-container


【解决方案1】:

回答问题 1 和 4

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

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

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

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

container.RegisterType<IQuestionnaireViewModel, QuestionnaireViewModel>();

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

回答问题 2

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

回答问题 3

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

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

【讨论】:

  • 你说 QuestionnaireViewModel 是一个具体的类,所以不使用依赖注入。而且我现在了解到您使用接口而不是具体类,因此您可以切换不同的视图模型。能够使用不同的视图模型有什么用?这是否只有在开发应用程序的团队而不是一个人的情况下才有用?
  • @JohnMcDonald 依赖注入可用于除视图模型之外的许多事情。在具体类上使用接口使您能够轻松切换代码中的依赖关系。例如,今天您可能使用Log4NetLogger 进行日志记录,但明天您想使用EnterpriseLibraryLogger。如果您使用ILogger 进行注入,您需要做的就是更改将记录器注册到容器的行。如果没有,则必须更改并重新编译每个使用记录器的类。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多