使用统一创建视图和视图模型
使用联合作为依赖注入容器类似于使用MEF,并且支持基于属性的注入和基于构造函数的注入。主要区别在于,这些类型通常不会在运行时被隐式发现;相反,它们必须在容器中注册。
通常,在视图模型上定义一个接口,这样视图模型的特定具体类型就可以与视图分离。例如,视图可以通过构造函数参数定义其对视图模型的依赖,如下所示。C#
公共QuestionnaireView() { InitializeComponent();} public QuestionnaireView(QuestionnaireViewModel viewModel):此(){ this.DataContext = viewModel;}
默认的无参数构造函数是允许视图在设计时工具(如Visual和Expression )中工作所必需的。
或者,您可以在视图上定义一个只写的视图模型属性,如下所示。统一将实例化所需的视图模型,并在视图实例化后调用属性设置器。C#
公共QuestionnaireView() { InitializeComponent();}依赖公共QuestionnaireViewModel ViewModel { set { this.DataContext = value;}
视图模型类型是在Unity中注册的,如下所示。C#
IUnityContainer容器;container.RegisterType();
然后可以通过容器实例化视图,如下所示。C#
IUnityContainer容器;var view = container.Resolve();
发布于 2011-12-23 15:55:52
回答问题1及4
在您的示例中,视图模型的类型是QuestionnaireViewModel,它是一个具体的类。由于它是一个具体的类,当您使用container.Resolve<QuestionnaireView>()解析视图时,统一将通过在幕后调用container.Resolve<QuestionnaireViewModel>()来为您实例化视图模型。
在这种情况下,注册视图模型是多余的。但是,在使用依赖项注入时,通常希望使用接口而不是类,因此构造函数如下所示:
public QuestionnaireView(IQuestionnaireViewModel viewModel)
{
this.DataContext = viewModel;
}既然您的构造函数接收到一个接口而不是一个类作为参数,团结就不知道您想要使用哪个接口的实现。要告诉Unity,您需要将视图模型注册到容器中:
container.RegisterType<IQuestionnaireViewModel, QuestionnaireViewModel>();现在,当您解析视图时,Unity将查找应该使用哪个类作为IQuestionnaireViewModel的实现,查看它是QuestionnaireViewModel并使用它。
回答问题2
因为为了使构造函数获得其参数,您需要使用容器解析视图。如果使用new QuestionnaireView()实例化视图,则不使用统一,即不会发生构造函数或属性注入。
回答问题3
我认为这主要是一个问题,什么是更舒适,你需要使用注入的成员。很多时候,您只想在构造函数中设置一个局部变量,而不是只为执行注入而创建一个属性。
但是,属性注入的一个好处是,您可以使用container.BuildUp()方法来处理通过使用new而不是container.Resolve<>()创建的实例。这样,即使在创建之后,也可以将成员注入到属性中--这是构造函数注入所不能做的事情。
https://stackoverflow.com/questions/8617277
复制相似问题