Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVVM and avoiding Monolithic God object

I am in the completion stage of a large project that has several large components: image acquisition, image processing, data storage, factory I/O (automation project) and several others.

Each of these components is reasonably independent, but for the project to run as a whole I need at least one instance of each component. Each component also has a ViewModel and View (WPF) for monitoring status and changing things.

My question is the safest, most efficient, and most maintainable method of instantiating all of these objects, subscribing one class to an Event in another, and having a common ViewModel and View for all of this.

Would it best if I have a class called God that has a private instance of all of these objects? I've done this in the past and regretted it.

Or would it be better if God relied on Singleton instances of these objects to get the ball rolling.

Alternatively, should Program.cs (or wherever Main(...) is) instantiate all of these components, and pass them to God as parameters and then let Him (snicker) and His ViewModel deal with the particulars of running this projects.

Any other suggestions I would love to hear.

Thank you!

like image 526
bufferz Avatar asked Jun 01 '10 15:06

bufferz


4 Answers

Take a look at some dependency injection frameworks such as Unity (which CAL uses), Castle Windsor or Spring.NET.

like image 197
treehouse Avatar answered Oct 19 '22 13:10

treehouse


These concerns are taken care of quite nicely using Microsoft's "Composite Application Library" (aka Prism) a framework for developing composite WPF applications:

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

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

  • Composing your views: Prism has a concept of an application shell window and a region manager. The shell acts as a bare-bones layout page where you define named place-holder regions e.g. "MainMenu" and "TabInterface". You wrap references up to your views and viewmodels in module classes e.g. "MainMenuModule" and "TabInterfaceModule", and define which region the module should be associated with. Prism will create your views and inject them into the shell regions when the application starts. This allows you to compose your views independently of each other.

  • Communication between viewmodels: Prism supports a mediator pattern called the "Event Aggregator". Basically you can publish and subscribe to messages via the event agregator from your viewmodels. This allows viewmodels to loosely communicate via messages, rather than having to know about each other and hooking events.

Prism advocates and supports patterns for developing components independently of each other in a loosely coupled fashion, without introducing God objects and over coupling. A big part of Prism is also it's use of IOC and dependency injection, so unit testing becomes much easier too.

I found the following article a good practical introduction to using Prism and MVVM:

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

like image 29
Tim Lloyd Avatar answered Oct 19 '22 12:10

Tim Lloyd


My prefered way of getting ViewModels is using a ViewModelLocater. Basically it's the God object like you imply, but it's only responsibility is to create each ViewModel and keep a reference to it. I usually add the VML to the App's resources and each view is responsible for setting it's DataContext to the correct ViewModel. If you are subscribing multiple events you can either have your VML wire them up manually, or it can create the VM that throws the events first and pass it to the dependent VM in it's constructor.

like image 21
Stephan Avatar answered Oct 19 '22 13:10

Stephan


You might use Controllers (ApplicationController, Use-Case Controllers) instead of a ‘God’ class. The controllers are responsible to create the ViewModel objects and they mediate between them.

How this works is shown by the WPF Application Framework (WAF) project.

like image 24
jbe Avatar answered Oct 19 '22 12:10

jbe