How to create shared Model for 2 different Views? - c#

I create the instance of my model in ViewModel2. This is sufficient for most of data. However, I also have some data, which is presented in different View, which is operated by ViewModel1. Should I just go ahead and create singleton pattern using for example SimpleIOC then obtain model instance from ViewModel1? If there is more proper way to do that according to MVVM concept I would like to know.

Use an IOC container to hold the Model (or Data Access Layer to the model) and inject it into any ViewModels that require it. This is the pattern used by the MVVMLight framework (see https://msdn.microsoft.com/en-us/magazine/jj991965.aspx or start a new MVVMLight project in Visual Studio)

Related

Should viewmodels contain static functional methods?

If I have a Viewmodel designed to serve a purpose for a view -
Is it a good practice to add bunch of static methods to the viewmodel like
- getting a list of items(viewmodel object) by consuming data from db?
- updating the db using a property in the viewmodel?
I am using .NET MVC and feel like my viewmodels get cluttered with bunch of static functions and update methods.
The main reason behind creating viewmodel for the views was because the views started to contain a lot of functionalities for which info had to be fetched from all over the place. So instead, i decided to create a viewmodel to get the info from one place with one call.
Am I following a good coding pattern here? Or am I shooting in the dark?
Is it a good practice to add bunch of static methods to the viewmodel
No, your viewmodel should simply be a POCO, containing as little (if not zero) business logic. A view models only job is to move data from the controller to the view.
Generally:
The controller should obtain an instance of a model from somewhere
this can be consumed by the view directly or if multiple models needs
combining or extra information (not in a model per se) is required
then a view model can be created.
Ideally the view model should be created outside of the controller
(keeping the controllers job clean), this can be achived simply by
using a factory pattern
If you read the wikipedia page for the MVC pattern. You'll notice it is solely designed for the presentation of data, not business logic:
Model–view–controller (MVC) is a software architectural pattern for
implementing user interfaces.
so really none of the MVC objects (Model, View or controller) should contain business logic. The MVC patterns job is to render data (full stop)
That all said it is common to put simple business logic into the controller. Once sites get more complex, though, this should be avoided, for fear of creating a god object
Am I following a good coding pattern here?
No, it's not a good pattern.
The main reason behind creating viewmodel for the views was because the views started to contain a lot of functionalities for which info had to be fetched from all over the place. So instead, i decided to create a viewmodel to get the info from one place with one call.
Store functionalities or any kind of logic is not the ViewModel's purpose. It should be just a transport mechanism that holds the data transported between the View and the Controller.
Consider move your "funcionalities" to Application, Service or another layer that makes sense for your application's architecture.

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.

MVVM: How to maintain data which all the view models will use?

Maybe the title is not so descriptive.
I'm working right with Galasoft MVVM framework, and I realized in my application I need all the time or use these data in the view models.
The data which I need is this Authentification model
Username : string
Password : string
IsGuest : bool
I guess it is not a good idea and the best way to pass these data through navigation.
A few months ago, I was using Prism and I remember something called Container, where you can register and save your object in all the lifecycle of your application.
Another way which I was thinking is to save it in App class, but I'm not sure if this is a good idea.
By the way, I'm working on Metro UI applications.
Don't store the data in the App because it is part of the View. To use it you would effectively have to reference the View from all of your ViewModels. A core principle of MVVM is that the Model(s) only have access to other Model items, the ViewModel has access to other ViewModels and the Model, and the View has access to ViewModels
There are a couple of choices you could consider
Create a static class AuthenticationData where this gets initialized
Pass the authentication data to the constructor for each view model
Store the authentication data in an IoC container (GalaSoft has a SimpleIoc class)
Options 2 and 3 could make it easier to mock your authentication data for testing purposes if you use an IAuthenticationData interface
For Authentication there's already something there you can use. Check IPrincipal/IIdentity interfaces. Upon authentication these are set to Thread.CurrentThread.CurrentPrincipal and can be used later.
The Container you are referring is probably Unity which is an IoC container and GalaSoft also comes with a simple one.

MVVM C# Question

I am currently learning MVVM abd the tutorial I have been using, simply uses a single View Model with a single Model. The View Model is injected with the Model interface as such:
public ViewModel(IQuoteSource quoteSource)
{
}
This is handled via DI using Unity. My question is what if the VM is dependent on multiple Models, say an arbitrary 6 or 7? Do we simply inject each of them into the ctor or should there be seperate VM's for this?
Or should each model try to implement a specific interface that exposes a couple of methods/events such as register to hook into and then an event once the data has been updated?
Thanks.
That is a lot of models for your VM to depend on. You can inject all those on the constructor, this makes the dependence more explicit and visible. Or you can have the VM resolve the various models from the Unity container:
public ViewModel(IUnityContainer container)
{
IQuoteSource model1 = container.Resolve<IQuoteSource>();
... etc ...
}
When a concrete instance is resolved using Unity and you have not specified any constructor parameters in the Resolve() call, Unity will examine the constructors from most complicated to most basic, if it finds one that takes a Unity container then it will use it (it will potentially use others first if it finds them).1 So if your VM takes a Unity container in the constructor, it can then use that container to further resolve anything it needs.
Some may argue over which method is more suitable - direct injection of all required dependencies, or injecting just the container that has the dependencies. IMVHO there are positives and negatives to both approaches, use whichever suits your style better.
You could also consider refactoring your code somewhat, maybe introduce a new Model that is a facade over several existing models. The other possibility is what you have termed a Model may actually be more suitable as a service (a tell-tale sign of this is if the model is used in several places to fetch data from a specific source, if this is the case then you can separate out that functionality into a service and cart that around in the Unity container for it to be consumed as necessary).
1 Reference: Telling Unity Which Constructor to Use when Initializing a Class

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!
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.

Categories