I am using MVVM with WPF, but I am having a hard time understanding the concepts behind this desing pattern.
I have a "myclass" object that is the state of the application (it stores data loaded from the repository). All pages of my application will use this data and the object should be syncronized between them all.
My first approach was to store this data in the service layer, using a singleton class. So, all ViewModel should call this service to get the data. Any modification should also call this service, and a event would be fired to synchronize all views.
I am wondering now if it would be better to store this data in the model layer...
What's be best option?
EDIT:
Adding more information:
The data stored is a list of projects loaded into a solution. Since there must be only one solution, I implemented it as a singleton. The must can interactively load, change, or remove any project.
A Service to my understanding is just something that abstracts a piece of functionality(access the file-system, access a database...) which say implements a given interface that the VM's can then use when requiring that functionality.
A Model however holds the business logic of your application and anything that will assist performing that business logic (which can / cannot implement INPC if desired)
So in essence you use a service to get something done and let go of it, a Model is more ingrained to your application
For your given use-case, I'd have the stored info in the Model and implement INPC on it so that the ViewModels get notified of changes automatically if another ViewModel makes a change to the Model.
Related
I'm currently working on an application that implements the MVVM architecture, where I am trying to do the login logic.
I have a pretty good idea of what the main responsibilities of both INotifyPropertyChanged and ICommand are, and have already implemented them to all my view models that need them.
Here's a short of my code:
I have an ApplicationViewModel.cs that handles the main window ApplicationView.xaml.
The main
window has a sidebar menu on the left, and a <ContentControl> that that is binded to the CurrentViewModel property of type ViewModelBase in ApplicationViewModel.cs.
All child view models are contained in a List<ViewModelBase> property. It gets its views from a DataTemplate with the corresponding view model, thus providing me a working navigation system.
So here's what I initially thought of doing:
In a child view model called LoginViewModel.cs, I thought it was logical to do the login logic, as it also handled the view itself. I wrote a model class User.cs with corresponding properties to the database columns. I wrote some classes that would help me get the data from the database to the application.
The view model checks for how many characters are entered and executes the Login once the user has entered 4 characters for the pin code, which instantiates a User object in LoginViewModel.cs
The problem here for me, is that I need the instance of the User to be application wide and therefore probably needs be in the ApplicationViewModel.cs instead.
So, from that, I have 2 questions:
Is there a better approach to this and a better way handle the login logic?
If the logic I already made is fine, how do I hand the instance of the User from the child view model LoginViewModel.cs to the parent view model ApplicationViewModel.cs?
Yes; it wasn't quite natural to come towards this solution when I first started, but you actually can add some kind of 4th layer in MVVM, the Services layer (well, it's more of a pattern than an actual MVVM layer).
Services are single-instance objects that you inject into your viewmodels, and serve exactly that kind of purpose, which is holding and potentially treating data that should circulate between viewmodels.
You will need a dependency injector, a class that will bother with finding the correct service for the classes injected with it.
So you have two concepts to study:
Services
Inversion of control/dependency injection
I can't just give you an implementation of a dependency injector, because I personally don't have one.
I'm using a MVVM framework that provides me with one already.
It's basically used this way:
You create an interface for each of your services; it keeps concerns separated (no coupling between service implementations and viewmodels).
You register your service implementation by their interfaces (something like myDependencyInjector.Register<IMyService>(typeof(MyService)) at the start of your program
You add the desired service interfaces to the relevant viewmodels' constructors (MyViewModel(IMyService myService))
You could implement custom authentication and authorization by creating classes that derive from the IIdentity and IPrincipal interfaces and override the application thread's default identity. Please refer to the following blog post for more information about how to do this.
Custom authorization in WPF: https://blog.magnusmontin.net/2013/03/24/custom-authorization-in-wpf/.
You basically create an IPrincipal and use the AppDomain.CurrentDomain.SetThreadPrincipal method to associate this principal with the AppDomain in your application. You can then use the Thread.CurrentPrincipal.Identity.IsAuthenticated property everywhere in your application to determine whether the user is authenticated.
In the code sample, the actual authentication is done by the AuthenticationService class. You could for example implement this one to check the passed in credentials against a remote database. The view model uses this service to perform the authentication.
Recently, I'm learning MVVM design pattern!
In my way, I write the database function in the model, and let the viewmodel to call the database function in the model, then the viewmodel get database data and set to the viewmodel notfiypropertychanged. This is my way that I currently use!
There are some question confused me about model,
I read many article that told me model just a contain data and not more business logic, and here is my question, if model just a data container and I need to let my viewmodel to call the database then get data and set to the model, I think this way is very strange and the viewmodel code is make heavy in it. Is anybody have another method to do it? Thank you!
The Model:
"model just a contain data and not more business logic"
A model is a class which describe an entity within your domain logic. What is a domain? Starbuck's domain is coffee beverages and employees (among others), Ford's domain is cars, assembly lines, and employees. NYTimes's domain is articles, issues, supply routes, subscribers, etc, etc.
A model contains data AND logic. You can have multiple models to describe your domain.
You can place your data calls in your model, but it's more common to have helper classes, data access layers (DAL), keeping all your database calls in one place, and not spread them around.
The ViewModel:
The viewmodel sits between your domain model and your view. It's a class which expose properties of the model and represents the state of the view. The viewmodel may only exposes a subset of all the properties in the model that the UI needs to display, but it could also add properties of its own, for example; is the user in edit mode? have changes been made that needs saving? etc. The selling point with MVVM is that the UI binds to these properties on the viewmodel which is a mechanism to keep the UI up to date with changes, and this extra layer of abstraction conveniently decouples the view to any logic in your model making it more robust for code changes in either direction and testable. There's more to say on this topic, but I'll leave it to you to read on up it.
There are many good resources and info on the MVVM pattern; from blogs Model-View-ViewModel (MVVM) Explained, to Microsoft The MVVM Pattern and here on SO.
If you prefer videos, Pluralsight have good video tutorials on the MVVM pattern
Practical MVVM and WPF MVVM In Depths. They have a free 30-day trial.
"just a data container"
Such classes that only hold data to be passed around are often called Data Transfer Objects (DTO). It's common to keep them small and return collections of these from fetch database data method calls.
I've done some research in this and also found it quite confusing. First thing I like to point out is that code-patterns are abstract. Meaning that you have loads of different way to implement it / tweak it.
What most people have told me is that in "real-life" applications you usually have layers of services.
One of these services is where you get data from a database.
The Model job (in my opinion) is to give the developer knowledge about the database data and structure. One Model to one database-tabel.
It also helps in checking if the data is correct (Format checking, Type of data and so on) before sending it to the DB.
There isn't a clear answer on how to use model. I've seen loads of different implementations, and they all have been implemented for specific tasks.
Yes it might come out that some ViewModels become heavy-loaded with code and functions to perform, but then it might not be because of the code-pattern. It can be because of poor structure in code. At my work right now I've found a ViewModel that contained over 3000 lines of code (Which is WAY to much). This could easily be seperated into atleast 3 different ViewModels and Views, but as I said, poor code structure causes problem.
One thing I recommend for you to read up on is
IoC - Inversion of Control
DoP - Dependency inversion principle
DI - Dependency Injection
Hope this helps in someway explaining your question.
I read many article that told me model just a contain data and not more business logic
A model may be represented by a service, a database access layer or a business layer so there is nothing wrong with your current approach. The business logic does belong to the model.
But sometimes people tend to refer to a "child" type as a model. For example, if your view model exposes a List<Item> property, the Item class may considered to be a model. Perhaps your confusion comes from this.
This kind of classes (Item) typically implement the INotifyPropertyChanged interface to provide change notifications and are effectively rather just "nested" view models that don't contain any business logic though.
Hope that makes sense.
Still feeling my way through MVVM, and have come up against this issue:
I have a top level ViewModel, lets call it ModelLevel1.
I have a sub ViewModel that belongs to it, that a control uses for all its bindings, lets call that ControlViewModel1. The Control only binds to ControlViewModel1.
In the Top level Viewmodel, there is a Repository, and a method to get a record from the repository from an id.
What is the best way to allow ControlViewModel1 to access the method so it can get a record from the repository?
Cheers,
Rob
Following the Single Responsibility Principle extract the logic of getting the record to a class that knows how to do it and inject that dependency to both ViewModels.
This approach can be reused by other classes, can be easily tested and is performant (unlike the aggregated events proposal).
What is the best way to allow ControlViewModel1 to access the method so it can get a record from the repository?
IMHO Controls are self contained units which have dependency properties which serve the function of a VM; hence no VM is needed.
Create a Dependency property on the control which takes in the target VM and hence has access to the method.
Create a static property on the app which will contain the VM in question and access it as a static call.
MVVM is simply a separation of concerns, remember Xaml ultimately gets compiled into C# code which is executed along side the code. Whatever process you use in code to access methods and objects can also be carried over to control instances on the page.
I am currently developing a Microsoft Word Add-In that communicates with a backend via webservices. The dialogs in this Add-In are created with WPF and I make use of the MVVM pattern. The viewmodels communicate with the repository over services. In order to decouple viewmodel and services I use the DI-container framework Unity.
There is some kind of state (I call it "Context", similar to the http-context) that depends on the active document at the time a window/viewModel was created. This context contains stuff like the active user.
Since a picture is worth more than a thousand words, I prepared a diagram to illustrate the design.
Now my problem is, that when a service method is called, the service needs to know what the active context is in order to process the request.
At the moment I am avoiding this problem by having one service for each document. But since this cuts across the statelessness of services, I don't consider it as a durable solution.
I also considered passing the context to the viewModel, so that I can pass it back to the service when calling a method there. But I see three problems here:
Technical Problems:
Each time I want to resolve a Window with Unity I would have to pass a ParameterOverride-object with the context - what creates dependencies to the concrete viewModel implementation.
=> Or is there a better way to achieve this with unity?
Cosmetical Problems:
I would have to pass the Context as object since the class for it is part of the startup-project and the ViewModels are not. When I now want to obtain data from the context, I'd have to cast it.
Consider a windowViewModel that contains data for a TreeView with hundreds of TreeViewItems. I would have to pass the Context to each of these "TreeItemViewModels" if I'd want to call a service-method in one of these.
So I'm wondering if there is a way of automatically "injecting" (maybe reflection?) the context into the viewModel at runtime without the viewModel knowing anything about it. This is probably impossible to achieve with Unity, but I'm always open to being convinced.
On the other side, when a method on a service is called, the injected context is automatically extracted (maybe by some kind of layer in front the actual service) and saved into some globally accessible property.
I hope that some of you can help me. I appreciate any kind of idea.
I'm creating a simple network application that communicates with one or more services, so I planned to use some queues (for outgoing messages and incoming ones), a table, a list containing the status for each active connection, etc.: in other words, these are the data structures needed to ensure the functioning of the application itself.
This application must also be equipped with a graphical interface that shows part of the internal functioning of the application itself: for example, the filling status of queues, the status (detected speed, etc.) of the connections, etc.. According to the Model-View-ViewModel pattern, the model consists of the data to be displayed in the GUI: in this application, the aforementioned data structures represent the model. In other words, the Model implements the business logic of the application.
The ViewModel should implement INotifyPropertyChanged interface in order to notify the View that a change is occurred, but how does the Model to communicate with the ViewModel? After reading this article, I realize that the INotifyPropertyChanged interface is implemented by the model. This answer explains a little more, but it confuses me a bit:
INotifyPropertyChanged - Should go into ViewModel and Model (if needed)
Why, if needed?
When should I implement this interface?
When should I not implement it?
Moreover, the Dictionary does not implement the INotifyPropertyChanged interface: if I use it, should I wrap it with a class which implements this interface?
Finally, the model should be read-only, meaning that the user does not be able to change the contents of internal data structures using the GUI. How to accomplish this?
how does the Model to communicate with the ViewModel
Any way you want it to. In most of the apps we write, the view model makes calls to the business logic layer (the model). However, if you have a need for the view model to be notified immediately (events) of changes to the model, you could implement INotifyPropertyChanged on your model. Or you could simply have the view model subscribe to events on the model.
Moreover, the Dictionary does not implement the INotifyPropertyChanged interface: if I use it, should I wrap it with a class which implements this interface?
You only need to have the view model implement INotifyPropertyChanged. Properties within the view model (dictionary) will simply invoke NotifyPropertyChanged (or whatever your implementation looks like).
Finally, the model should be read-only, meaning that the user does not be able to change the contents of internal data structures using the GUI. How to accomplish this?
Don't provide the user the functionality to let them change the data. Make the binding one way, or simply don't provide them an API for making changes.
INotifyPropertyChanged is primarily implemented by the ViewModel classes. This is to facilitate the data-binding so that the UI controls in the view that are bound to the ViewModel property will be updated when the property is modified.
In the MVVM design pattern, the relationships are very simple and in a single direction. The View knows it's ViewModel and a ViewModel knows about the Model. If the Model is updated, the ViewModel needs to know somehow so that it can reflect the update and propogate it to the View. One way is to also have the Model implement INotifyPropertyChanged and have the ViewModel implement the corresponding event handler. If all the changes are driven from the UI and being pushed back to the Model, then this is probably not necessary.
You can't really bind to a Dictionary. Using an ObservableCollection would be ideal if that works in your case. Or, you can take a look at implementing an Observable Dictionary along the lines of this: http://drwpf.com/blog/2007/09/16/can-i-bind-my-itemscontrol-to-a-dictionary/
MVVM has provided separation of the Model from the View, so there should be no direct relationship from the View to the Model. The implementation of the ViewModel controls what, if anything would ever get written back to your Model.
INotifyPropertyChanged (INPC) should never be in the model unless the model is also the ViewModel (i.e. you don't have a "model"). INPC should only ever be in the view model.
The model should know nothing about the view model, and thus can never communicate with it. Only the view model can communicate with the model.
From the UI point of view, only the view model does anything with data; so, if you want the model to be "read only", then just don't implement that in the view model.
Binding would be done with the view model, in which case don't use Dictionary (unless you want to write the code to wrap that in order to bind it). If the Dictionary is in the model, then you should be "wrapping" that in the view model--it's fairly trivial to write an observable wrapper around a collection. In all likelihood your view model isn't going to deal with key/value pairs--it should be dealing with something flat that the UI can handle (and be bound to).
UPDATE:
INPC was introduced for data binding. It decouples a view from a particular concrete class so that it only needs to know about INPC (notice the direction of decoupling). In terms of MVVM this decouples the view from the view model, in the case of PM, this could decouple the view from the presenter, in the case of MVC this could decouple the view from the controller, in the case of MVP this decouples the view from the presenter.
Data binding is a technique of binding data to UI elements. It binds a data source to a target so that the target may request data how ever it sees fit or the source can push data however it sees fit (depending on the type of binding--it could be one-way or static, restricting how often get/push can occur).
Sometimes the necessary nature of the decoupled relationship between the data source and the target lead people to believe data binding isn't a UI concern and data binding can apply anywhere. i.e. a data binding implementation is completely decoupled from a UI. This is generally a mistake. Data binding decouples the view from the specific knowledge of specific classes (this is basic layering and avoidance of cycles, that I won't get into here). But, it doesn't completely decouple the view from the data source. Binding can't happen without the data source--there is still a level of coupling there, it's just the compile-time coupling that has been alleviated (aids in testing, flexibility, robustness, etc. but must be present at runtime in production. i.e. the fact that the INPC implementation can be tested without being bound at runtime to UI elements doesn't mean it's not dependant on a UI framework). The fact that the view is still loosely coupled to the data source isn't the only coupling in this relationship. The data source is loosely (if not less loosely) coupled to the view by way of its UI framework.
Every UI framework has a restriction that access and modification of UI elements must be done on the main, or UI, thread. (at least on Windows; it likely happens on other platforms, I'm just not proficient in any others). With data binding, the source is indirectly bound to the control and any data change directly changes one or more UI elements (depending on the framework you can have intermediaries. Like value converters in WinRT, but their responsibility is to transform or convert data). This means that the data source needs to have intimate knowledge that it is bound to a UI and what type of UI framework it is binding to. This tight coupling to a UI framework clearly couples the data source (still loosely) to the UI.
This means any particular implementation of INPC is really bound to one and only one UI framework. That object can no longer be used anywhere (obviously anywhere is an ideal, it's often impossible to make anything work for every scenario--the point here is high cohesion in more than just one or two scenarios). e.g. if an implementation of INPC is used in a multi-threaded environment then it needs to "marshal" data back to the UI thread before sending out property notifications. In WinForms, that's Control.BeginInvoke, in WPF and Silverlight that's via System.Windows.Threading.Dispatcher. In WinRT, that's via Windows.UI.CoreDispatcher. In all cases the INPC implementation must take a direct coupling to one UI framework. In the case of Silverlight, that's a direct coupling to either the "desktop" Dispatcher or the Windows Phone Dispatcher.
Quality metrics include concepts like cohesion. Cohesion is a measure of how strongly related two units of code are. An implementation of INPC that is used by something other than the UI, due to the nature of all the infrastructure required to support that one particular UI framework, although potentially able to be used outside of the UI, will have low cohesion because all of the code relating to the UI framework will not be used. i.e. it's take on too much responsibility to be completely decoupled from the UI. Yes, you can use an object that implements INPC anywhere and never use the PropertyChanged event, but then you have low coehsion (considered bad).
If I implemented INPC in my model and I wanted to use that model with both my UI and my WCF or web service back end, I either couldn't or my backend would have to take a reference to some UI framework. If I wanted to use that model in another type of UI, I couldn't, because that INPC implemetnation depends on one particular UI framework. I'd have to write another "model"; at which point it's clearly a "view model".
INPC itself is not bound to a particular UI framework (nor should it be). This leads to the misconception that INPC can be used anywhere. Yes, its lack of coupling to high-level namespaces means it can, but the overwhelming usage of INPC is when the target is a UI. I'd challenge any other uses of INPC that don't involve a UI as true "binding". As with any other tool, you can misuse it to get useful results. INPC could be used for projecting data, it could be used for transforming data, etc.; but I believe those are misuses of INPC and really outside the focus of this question...