MVVM并避免使用Monolithic God对象

时间:2010-06-01 15:59:42

标签: c# wpf mvvm god-object

我正处于一个大型项目的完成阶段,该项目有几个大型组件:图像采集,图像处理,数据存储,工厂I / O(自动化项目)和其他几个。

这些组件中的每一个都是相当独立的,但是要使项目作为一个整体运行,我需要每个组件至少一个实例。每个组件还有一个ViewModel和View(WPF),用于监视状态和更改内容。

我的问题是实例化所有这些对象的最安全,最有效和最易维护的方法,将一个类订阅到另一个类中的Event,并为所有这些提供一个共同的ViewModel和View。

如果我有一个名为God的类,它拥有所有这些对象的私有实例,那会不会最好?我过去做过这件事而后悔了。

或者如果上帝依靠这些物体的单身实例让球滚动,会不会更好。

或者,如果Program.cs(或Main(...)所在的地方)应该实例化所有这些组件,并将它们作为参数传递给God,然后让他(窃笑)和他的ViewModel处理运行这个的细节项目

我希望听到的任何其他建议。

谢谢!

5 个答案:

答案 0 :(得分:3)

使用Microsoft的“复合应用程序库”(又名Prism)开发复合WPF应用程序的框架,可以很好地解决这些问题:

http://msdn.microsoft.com/en-us/library/ff647752.aspx

http://msdn.microsoft.com/en-us/library/ff648611.aspx

  • 撰写观点:Prism有一个应用程序shell窗口和区域管理器的概念。 shell充当一个简单的布局页面,您可以在其中定义命名的占位符区域,例如“MainMenu”和“TabInterface”。您可以将引用包装到模块类中的视图和视图模型中,例如“MainMenuModule”和“TabInterfaceModule”,并定义模块应与哪个区域相关联。 Prism将创建您的视图,并在应用程序启动时将它们注入shell区域。这使您可以相互独立地构建视图。

  • 视图模型之间的通信:Prism支持称为“事件聚合器”的中介模式。基本上,您可以通过视图模型中的事件agregator发布和订阅消息。这允许视图模型通过消息进行松散的通信,而不必了解彼此并挂钩事件。

Prism倡导并支持以松散耦合的方式彼此独立地开发组件的模式,而不引入上帝对象和过度耦合。 Prism的一个重要部分也是使用IOC和依赖注入,因此单元测试也变得更加容易。

我发现以下文章是使用Prism和MVVM的一个很好的实用介绍:

http://www.developmentalmadness.com/archive/2009/10/03/mvvm-with-prism-101-ndash-part-1-the-bootstrapper.aspx

答案 1 :(得分:3)

看看一些依赖注入框架,例如Unity(CAL使用),Castle Windsor或Spring.NET。

答案 2 :(得分:2)

我首选获取ViewModel的方法是使用ViewModelLocater。基本上它就像你暗示的上帝对象,但它的唯一责任是创建每个ViewModel并保持对它的引用。我通常将VML添加到App的资源中,每个视图负责将其DataContext设置为正确的ViewModel。如果您正在订阅多个事件,您可以让您的VML手动连接它们,或者它可以创建首先抛出事件的VM并将其传递给它的构造函数中的依赖VM。

答案 3 :(得分:1)

您可以使用控制器(ApplicationController,用例控制器)代替“上帝”类。控制器负责创建ViewModel对象,并在它们之间进行调解。

WPF Application Framework (WAF) 项目会显示其工作原理。

答案 4 :(得分:0)

我希望我能很好地理解你的问题。我认为使用God ViewModel并不是一个好主意。最好为每个视图设置一个viewmodel,并在该viewmodel中实例化所有相关的viewmodel。然后,您可以使用中介在该视图的视图模型和其他视图之间发送消息。我也建议使用wpf命令而不是事件。你可以在here找到一篇关于调解员的文章。