MVVM and avoiding Monolithic God object - c#

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!

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

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

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.

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.

I hope I have understood your question well. I think using a God ViewModel its not a good idea. its better to have a single viewmodel for each of your views and instantiate all the related viewmodels in that viewmodel. then you can use a mediator to send message between viewmodels of that view and other views, safly. also i propuse to use wpf commands instead of events. you can find a greate article about mediator in here.

Related

WPF MVVM communicate between views

Lets assume I have a button in View A which should trigger functionality of View B. How is this preferably done? I could use the Mediator but I prefer to avoid it and mainly use it for communication between viewmodels where there is absolutely no other way.
Here is a thought of mine:
So basically we have an interceptor class that handles communication between multiple views. The view doesnt know about the other views. The interceptor acts as a messenger between them.
Is this ok in terms of thinking in MVVM?
Most MVVM frameworks contains a mediator of some kind for this purpose.
In MvvmLight it is called Messenger and in Prism it is called EventAggregator. For example.
And the mediator can be used to communicate between any two components, be it a view or a view model, in a loosely coupled way.
So you are basically describing the mediator pattern here. Don't reinvent the wheel :)

How to create and organize non UI related elements using the MVVM pattern

I'm creating a WPF application using the MVVM design pattern. I've only recently started learning both, but have a solid grasp on how the basics work.
The application will have classes that are not UI related, such as a networking thread and message handler, and a class to save and load settings.
These elements of the program don't have a clear connection with the UI. How should they be created and initialized? These are "application wide" services that will not fit a particular ViewModel, and don't feel like a Model either.
Is there a correct way to do this? What should "own" and create these objects? (The ViewModel, or rather make them static and create themselves?)
Here is a diagram of the MVVM model, with a few adjustments to show what I am looking for: (Highlighted text and purple box)
When a "user has joined" message is received the the server, the service will send an event to the model that has subscribed to it, notifying it of the new user. The ViewModel will see this change, and add the user's name to the UI.
You can have services that are linked to a certain functionality of a UI. (Only the main windows uses them, for example) And there can also be services that are shared between many windows.
For the first scenario, I usually instantiate the services in my ViewModels.
For application wide services, I'd rather create the instances in App.xaml.cs and pass the reference to my viewmodel.
Here is an example from one of my projects.
private void Application_Startup(object sender, StartupEventArgs e)
{
ConnectionManager connMan = new ConnectionManager();
MainViewModel mvm = new MainViewModel(connMan);
new MainWindow(mvm).ShowDialog();
// TODO: save settings, etc. here
this.Shutdown();
}
If your services do not rely on any state information, you could use static classes as well. And that is what I usually use for settings management, for example.
Edit: For the example you've posted, you have to ask yourself this question:
Who is responsible for creating and maintaining the network manager object?
If it is the ViewModel, it can host the object inside itself. If it is created by an external object, you would pass it to the ViewModel. There are pros and cons to either approach and I don't have enough information to suggest you one of them right now.
You can use a DI Container and register your services with it. It is then a matter of personal preferences if you use Dependency Injection or use the DI Container as a mere Service Locator.
The basic idea behind a service locator is to have an object that knows how to get hold of all of the services that an application might need. So simply speaking ServiceLocator is a singleton Registry.
The basic idea of the Dependency Injection is to have a separate object, an assembler, that populates a field in the lister class with an appropriate implementation.
A good implemantion is the Microsoft Unity Container. You can use it as an DI container or a Service Locator.
In this situation, try to keep a List (eg ObservablleCollection<T>) in the ViewModel, and model-specific data type like Person, User in Model.
Then create separate namespaces such as Workers, Helpers or Managers, which are static classes that are only responsible for their specific area. For example: Workers / Sql / SqlWorker, Workers / Network / NetworkWorker.
Later in the ViewModel, call these methods in the appropriate commands.
I think it would be a simple and advanced solution, since workers will not interfere with each other (if only via abstract interfaces), besides they will not be connection to the UI.

How to communicate between two MVVM pairs?

I have a little app with a overview of some items (entries). The title of the entry at the list in the overview is a property of the entry.
When I click an entry a kind of tab should open where I can edit the entry. When I edit and save the entry, the overview tab should update the next time.
Here a mockup for better understanding.
App is based on MVVM pattern. Each View has a ViewModel as DataContext. Each ViewModel uses a Model and each Model has a Database.
The overview tab have it's own View, ViewModel and Model (pair). Also the tabs. Each tab for entries use the same pair (singleton instance). Only a few bindings are updated If a other tab is selected.
My question is how to communicate between the tabs.
I have two approaches
Mediator Pattern (Bootstrapper combines two ViewModels with a mediator)
Each Model uses the same Database (Models listen to Database, ViewModel listen to Model)
But I dont' feel well with these approaches.
Should I communicate between Models or between ViewModels? Or is this the wrong way?
UPDATE
I really appreciate all of your answers. In my opinion none of them are wrong or right. I think it's a matter of taste which solution is right for one is. I really like the EventAggregator pattern. Here is a nice video from Karl Shifflett about the implementation of the EventAggregator pattern in PRISM. But it also explains the pattern itself.
#Thomas In my opinion it is a bad solution to do this in one ViewModel. ViewModels have to be separated. MVVM based on Separation of Concerns.
Mediator is a step in a right direction but an Event Aggregator is much more flexible. You can find dozen of implementations. For example, Prism has a ready-to-use implementation.
Communication is between ViewModels. ViewModels register themselves for notifications in the Aggregator and raise notifications on the Aggregator.
You should communicate between ViewModels, if the functionality is related to formatting Model data for display. If your are communicating data from one Model to another, then communicate between Models.
Here is a concrete example: The Microsoft.Practices.Prism namespace, which you can access with NuGet right in Visual Studio, includes a class called CompositePresentationEvent<T>, along with an EventAggregator class which does the actual communicating.
Someplace common to your entire application (I chose App.xaml.vb, but it can be any publicly scoped code file, and it works as well for C# as for VB), you define events by inheriting from that class, and supplying the type T which corresponds to the data you're sending. For example, if you want to send a message that contains a simple string, then declare:
Public Class MyEvent: Inherits CompositePresentationEvent(Of String) : End Class
In your Application class, you define an event aggregator:
Public Shared ReadOnly AppEventAggregator As IEventAggregator = New EventAggregator()
Those two items together give you the means to trade events between any two objects in your application.
This gives your entire application access to an event called MyEvent. Wherever you want to send the MyEvent message, you call its shared Publish(String) method:
Application.AppEventAggregator.GetEvent(Of MyEvent).Publish("This is my event message")
Then, to receive the event, you implement a private read-only field in the class where the event should land, something like:
Private ReadOnly MyEventToken As SubscriptionToken =
Application.AppEventAggregator.GetEvent(Of MyEvent).Subscribe(Sub(eventMessage) DoSomethingWithTheString(EventMessage))
...where DoSomethingWithTheString(eventMessage As String) would be where you process your event.
There's (a lot) more to Prism, of course, but never a need to use more of it than you need, and, as others have pointed out, lots of other MVVM frameworks with similar approaches to solving the same problem.
For me, it's usually a bad sign when I have to program for communication between view models. Sometimes, you have to make communication between view and view model, but the need for connecting two view models seems to always result in combining two view models if possible.
With your mockup, I felt the same bad feeling. Why do you have to have separate view models for tabs in first place? In your case, views can be separate but I don't see any benefit from separating view models. Thus, combining the two view models into one is my recommendation.
Maybe this Post is interesting for you, it Describe a Pattern for a Communication on Type basis. It allows you to Communicate between everything you want, without dependences between them

EventAggregator Pattern: How To Pass Data?

I am looking at utilizing the Event Aggregator Pattern on a UI project I am working on (Silverlight/MVVM) to support loose coupling between views/viewmodels. We have written a few screens using a simple eventing system--it's not much more than a proof of concept at this point, but it does seem like a very elegent solution to creating a loosely coupled system.
The problem I am running up against is passing data from one ViewModel to another when the receiving ViewModel is not instantiated yet. For example, if a Customer List screen is open, a user might click a specific customer to open an edit/view Customer Detail screen (perhaps in a child window). The Customer Detail screen needs a customer (or customer Id) in order to function.
So is seems reasonable that the OpenCustomerDetailEvent would contain the relevant customer information, but what are some options for injecting that information into the Customer Detail V/VM? Since it's not in memory yet when the event is handled, it can't directly listen for the event (it can't itself be the handler). We are using a depenency injection container to create both the view and view model (we currently do "view first"), so having a separate handler inject the data via the constructor is not a great option.
What are some other options for getting the data into the View(Model) once it's constructed? An init method that takes strongly typed parameters? Using a setter to inject the data? Having the handler create the V/VM and then dispatch a second event that the VM listens for?
For this purpose i´m using the Prism Framework in my silverlight application. It provides an implementation of the EventAggregator pattern and a view navigation infrastructure.
In the case of prism, you will use NavigationParameters, that provide information for a view/viewmodel what data to use and to initialize. If the view/viewmodel isn´t created yet, the EventAggregator pattern is useless, cause it isn´t registered to the event yet.
If you want to rely on your own framework, i would take a look at the prism framework how view navigation is implemented there and to pick up some pieces for your own framework.
Personally i would encourage you, to use the prism framework.

WPF: MVP vs MVVM

What is the difference between MVP VS MVVM? Why we are using MVP even though we have three layers: business, data access and presentation? Is there any specific reason to divide the Presentation layer into MVP?
MVP and MVVM are both derivatives of MVC. MVC is a pattern that separates the user presentation and interaction from the internal representation.
This requires three layers, since tying the user interaction/presentation directly to the internal representation will cause both to bend to conform to each other. In your application, you described these layers as the Presentation, the Business layer, and the Data Access layer. With only those very loose descriptions, you could potentially be describing any of the MVC derivatives, or the original MVC pattern itself.
The key differences between each of the derivatives are the dependencies each layer takes on the other layers, and how tightly they are bound to each other. This article has some details on the differences, though of course it shouldn't be considered authoritative:
http://nirajrules.wordpress.com/2009/07/18/mvc-vs-mvp-vs-mvvm/
"... MVVM is attractive for platforms which support bi-directional binding with less effort. Also a minor tradeoff is ViewModel unlike Presenter can stand on its own (Presenter normally requires a View’s interface)."
We use at our company projects of WPF desktop application MVP instead of the built in MVVM for the main reason that in MVP the presenter is the main entry point that knows everything and no one knows about the presenter.
For each View the presenter which have one responsibility which is taking interactions from the IView interfaces by subscribing to events that the View triggers.
The presenter updates the View by a properties that encapsulates the internal View controls like TextBox with string properity and GridView with any Collection property. The constructor of the MainPresenter class will look something like this MainPresenter(IMainView, IEmployeeStore, IOtherDependency,..)
The Constructor of MainView class will look like this MainView(IPartialViewIfExists,..) that means the view does not know anything about the Presenter or anything else outside the View layer (which is the opposite of MVVM that enforces the MainView to directly couple the MainViewModel to automate the
two way databinding).
That clean loosely coupling architecture which the MVP provides is really powerful and flexible which enables the ability for the following:
Your application can replace the GUI with anytime without changing anything in the presenter, you can also change the GUI technology to something else like WinForms or something.
You can separate your GUIs in a separate project that doesn't require any dependencies of your main application like the presenters and dataAccesses
Your View can be used for any other application witch is useful for general GUIs.
You can unit test the views, the presenters and the data access classes easily.
The ViewModel in MVVM doesn't know about the View but I don't think that is helpful since it is responsible for the View. The View shouldn't know about the presenter which handles business logic and that's what exactly the MVP provides (or the way that we implement MVP).
That doesn't mean that MVVM is bad. MVVM is a good architecture and faster to code and easier to start with since it is already implemented in WPF and Xamarin but as I explained we prefer MVP for listed reasons.
In general MVP is cleaner and more scalable but requires more knowledge and coding experience and have to be implemented manually. MVVM is already there, it is easy to use and lets you implement faster but provides coupling and has some limitations. They all have their pros and cons and it depends on your need.

Categories